Собрал в Линуксе тулчейн для Винды под ABI-call0. Так называемая "канадская" кросс-компиляция 🙂
Теперь можно забыть о головной боли, связанной с регистровыми окнами, контроле/подмене стека, исключениях.
В ABI=call0 эти исключения не нужны: Window owerflow/underflow, Alloca, Syscall.
Вся работа с регистрами процессора прозрачна и в стиле "обычных" архитектур. А также доступны манипуляции с указателем стека для резервирования временных данных(стековые фреймы).
Простейший рабочий стартап выглядит так:
.section .entry.text,"x"
.align 4
.global Start
Start:
j BypassLiteral
.section .literal,"a"
.global Literal
Literal: //Literals located here
.text
.align 4
.global BypassLiteral
BypassLiteral:
movi a0,0 //disable all interrupts
wsr.intenable a0
movi a0,VECTORS //vector table base address
wsr.vecbase a0
movi a0,0 //PS.WOE = 0, PS.UM = 0, PS.EXCM = 0, PS.INTLEVEL = 0
wsr.ps a0
rsync
/*
Xtensa® Instruction Set Architecture (ISA) Reference Manual
8.1.9 Stack Initialization. p. 618
*/
movi a0,0
movi sp,__stack-16
addi a4,sp,32 //point 16 past extra save area
s32e a4,sp,-12 //access to extra save area
call0 libc_init
call0 board_init
call0 main
Пример как выглядит обработчик прерывания:
//...
.org 0x1FC //Kernel (IntLevel1) Vector
j Kernel
//...
.align 4
Kernel:
addi sp,sp,-64
s32i a0,sp,0
s32i a2,sp,4
s32i a3,sp,8
s32i a4,sp,12
s32i a5,sp,16
s32i a6,sp,20
s32i a7,sp,24
s32i a8,sp,28
s32i a9,sp,32
s32i a10,sp,36
s32i a11,sp,40
s32i a12,sp,44
s32i a13,sp,48
s32i a14,sp,52
s32i a15,sp,56
movi a2,PS_INTLEVEL(1) //mask interrupts to prevent stack corrupt in C/C++ calls
wsr.ps a2
rsync
call0 INTC_Handler
l32i a15,sp,56
l32i a14,sp,52
l32i a13,sp,48
l32i a12,sp,44
l32i a11,sp,40
l32i a10,sp,36
l32i a9,sp,32
l32i a8,sp,28
l32i a7,sp,24
l32i a6,sp,20
l32i a5,sp,16
l32i a4,sp,12
l32i a3,sp,8
l32i a2,sp,4
l32i a0,sp,0
addi sp,sp,64
rfi 1
Дополнительно собрал libhal(включение кеширования для DSP) под ABI-call0 из исходников.
Скачать GCC-тулчейн и исходники либы libhal (вместе с готовой либой) под ABI=call0 для T113-s3 HiFi4 DSP.