diff --git a/artiq/devices/runtime.py b/artiq/devices/runtime.py index 59b014307..3a5d87f84 100644 --- a/artiq/devices/runtime.py +++ b/artiq/devices/runtime.py @@ -62,6 +62,10 @@ class LinkInterface: self.llvm_module.add_function(func_type, "__syscall_"+func_name) # exception handling + func_type = lc.Type.function(lc.Type.int(), [lc.Type.pointer(lc.Type.int(8))]) + function = self.llvm_module.add_function(func_type, "__eh_setjmp") + function.add_attribute(lc.ATTR_NO_UNWIND) + func_type = lc.Type.function(lc.Type.pointer(lc.Type.int(8)), []) self.llvm_module.add_function(func_type, "__eh_push") @@ -90,11 +94,10 @@ class LinkInterface: return r def build_catch(self, builder): + eh_setjmp = self.llvm_module.get_function_named("__eh_setjmp") eh_push = self.llvm_module.get_function_named("__eh_push") - setjmp = lc.Function.intrinsic(self.llvm_module, - lc.INTR_EH_SJLJ_SETJMP, []) jmpbuf = builder.call(eh_push, []) - exception_occured = builder.call(setjmp, [jmpbuf]) + exception_occured = builder.call(eh_setjmp, [jmpbuf]) return builder.icmp(lc.ICMP_NE, exception_occured, lc.Constant.int(lc.Type.int(), 0)) diff --git a/soc/runtime/Makefile b/soc/runtime/Makefile index b8257ad8f..47fde5051 100644 --- a/soc/runtime/Makefile +++ b/soc/runtime/Makefile @@ -3,7 +3,7 @@ include $(MSCDIR)/software/common.mak BOARD=papilio_pro SERIAL=/dev/ttyUSB1 -OBJECTS=isr.o elf_loader.o exceptions.o services.o corecom_serial.o gpio.o rtio.o dds.o main.o +OBJECTS=isr.o elf_loader.o exception_jmp.o exceptions.o services.o corecom_serial.o gpio.o rtio.o dds.o main.o all: runtime.bin diff --git a/soc/runtime/exception_jmp.S b/soc/runtime/exception_jmp.S new file mode 100644 index 000000000..a537472fe --- /dev/null +++ b/soc/runtime/exception_jmp.S @@ -0,0 +1,41 @@ +.global exception_setjmp +.type exception_setjmp,@function +exception_setjmp: + l.sw 0(r3), r1 + l.sw 4(r3), r2 + l.sw 8(r3), r9 + l.sw 12(r3), r10 + l.sw 16(r3), r14 + l.sw 20(r3), r16 + l.sw 24(r3), r18 + l.sw 28(r3), r20 + l.sw 32(r3), r22 + l.sw 36(r3), r24 + l.sw 40(r3), r26 + l.sw 44(r3), r28 + l.sw 48(r3), r30 + l.jr r9 + l.ori r11,r0,0 + +.global exception_longjmp +.type exception_longjmp,@function +exception_longjmp: + l.sfeqi r4, 0 + l.bnf 1f + l.addi r11, r4, 0 + l.ori r11, r0, 1 +1: l.lwz r1, 0(r3) + l.lwz r2, 4(r3) + l.lwz r9, 8(r3) + l.lwz r10, 12(r3) + l.lwz r14, 16(r3) + l.lwz r16, 20(r3) + l.lwz r18, 24(r3) + l.lwz r20, 28(r3) + l.lwz r22, 32(r3) + l.lwz r24, 36(r3) + l.lwz r26, 40(r3) + l.lwz r28, 44(r3) + l.lwz r30, 48(r3) + l.jr r9 + l.nop diff --git a/soc/runtime/exceptions.c b/soc/runtime/exceptions.c index aa6b8a88a..b284236f5 100644 --- a/soc/runtime/exceptions.c +++ b/soc/runtime/exceptions.c @@ -1,9 +1,10 @@ #include "exceptions.h" +#include "corecom.h" #define MAX_EXCEPTION_CONTEXTS 64 struct exception_context { - void *jb[5]; + void *jb[13]; }; static struct exception_context exception_contexts[MAX_EXCEPTION_CONTEXTS]; @@ -29,5 +30,5 @@ int exception_getid(void) void exception_raise(int id) { - __builtin_longjmp(exception_contexts[--ec_top].jb, 1); + exception_longjmp(exception_contexts[--ec_top].jb, 1); } diff --git a/soc/runtime/exceptions.h b/soc/runtime/exceptions.h index 1011f0d50..7ece718b6 100644 --- a/soc/runtime/exceptions.h +++ b/soc/runtime/exceptions.h @@ -5,6 +5,9 @@ enum { EID_NOMEM = 0 }; +int exception_setjmp(void *jb) __attribute__((returns_twice)); +void exception_longjmp(void *jb, int val) __attribute__((noreturn)); + void *exception_push(void); void exception_pop(int levels); int exception_getid(void); diff --git a/soc/runtime/main.c b/soc/runtime/main.c index 6c45a72b8..7cd1fc6c0 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -77,7 +77,7 @@ static int run_kernel(const char *kernel_name, int *eid) } jb = exception_push(); - if(__builtin_setjmp(jb)) { + if(exception_setjmp(jb)) { *eid = exception_getid(); return KERNEL_RUN_EXCEPTION; } else { diff --git a/soc/runtime/services.c b/soc/runtime/services.c index 7d6fd5bab..74ef1a64d 100644 --- a/soc/runtime/services.c +++ b/soc/runtime/services.c @@ -21,6 +21,7 @@ static const struct symbol syscalls[] = { }; static const struct symbol eh[] = { + {"setjmp", exception_setjmp}, {"push", exception_push}, {"pop", exception_pop}, {"getid", exception_getid},