Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 8b769a04171f
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4d3d15ad9967
Choose a head ref
  • 3 commits
  • 9 files changed
  • 1 contributor

Commits on Sep 23, 2014

  1. Copy the full SHA
    af15f45 View commit details
  2. Copy the full SHA
    f7075b2 View commit details
  3. Copy the full SHA
    4d3d15a View commit details
Showing with 88 additions and 27 deletions.
  1. +6 −3 artiq/devices/runtime.py
  2. +8 −3 artiq/py2llvm/ast_body.py
  3. +24 −17 artiq/transforms/inline.py
  4. +1 −1 soc/runtime/Makefile
  5. +41 −0 soc/runtime/exception_jmp.S
  6. +3 −2 soc/runtime/exceptions.c
  7. +3 −0 soc/runtime/exceptions.h
  8. +1 −1 soc/runtime/main.c
  9. +1 −0 soc/runtime/services.c
9 changes: 6 additions & 3 deletions artiq/devices/runtime.py
Original file line number Diff line number Diff line change
@@ -62,6 +62,10 @@ def init_module(self, module):
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 @@ def build_syscall(self, syscall_name, args, builder):
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))
11 changes: 8 additions & 3 deletions artiq/py2llvm/ast_body.py
Original file line number Diff line number Diff line change
@@ -299,14 +299,19 @@ def _handle_exception(self, function, finally_block, propagate, handlers):
else:
if isinstance(handler.type, ast.Tuple):
match = self.builder.icmp(
lc.ICMP_EQ, eid, handler.type.elts[0].args[0].n)
lc.ICMP_EQ, eid,
lc.Constant.int(lc.Type.int(),
handler.type.elts[0].args[0].n))
for elt in handler.type.elts[1:]:
match = self.builder.or_(
match,
self.builder.icmp(lc.ICMP_EQ, eid, elt.args[0].n))
self.builder.icmp(
lc.ICMP_EQ, eid,
lc.Constant.int(lc.Type.int(), elt.args[0].n)))
else:
match = self.builder.icmp(
lc.ICMP_EQ, eid, handler.type.args[0].n)
lc.ICMP_EQ, eid,
lc.Constant.int(lc.Type.int(), handler.type.args[0].n))
self.builder.cbranch(match, handled_exc_block, cont_exc_block)
self.builder.position_at_end(handled_exc_block)
self.builder.store(lc.Constant.int(lc.Type.int(1), 0), propagate)
41 changes: 24 additions & 17 deletions artiq/transforms/inline.py
Original file line number Diff line number Diff line change
@@ -218,30 +218,37 @@ def visit_FunctionDef(self, node):
def visit_Raise(self, node):
if node.cause is not None:
raise NotImplementedError("Exception causes are not supported")
exception_class = self.rm.get(self.obj, self.func_name, node.exc)
if node.exc is not None:
exception_class = self.rm.get(self.obj, self.func_name, node.exc)
if not inspect.isclass(exception_class):
raise NotImplementedError("Exception must be a class")
exception_id = self.rm.exception_map[exception_class]
node.exc = ast.copy_location(
ast.Call(func=ast.Name("EncodedException", ast.Load()),
args=[value_to_ast(exception_id)],
keywords=[], starargs=None, kwargs=None),
node.exc)
return node

def _encode_exception(self, e):
exception_class = self.rm.get(self.obj, self.func_name, e)
if not inspect.isclass(exception_class):
raise NotImplementedError("Exception must be a class")
raise NotImplementedError("Exception type must be a class")
exception_id = self.rm.exception_map[exception_class]
node.exc = ast.copy_location(
ast.Call(func=ast.Name("EncodedException", ast.Load()),
args=[value_to_ast(exception_id)],
keywords=[], starargs=None, kwargs=None),
node.exc)
return node
return ast.copy_location(
ast.Call(func=ast.Name("EncodedException", ast.Load()),
args=[value_to_ast(exception_id)],
keywords=[], starargs=None, kwargs=None),
e)

def visit_ExceptHandler(self, node):
if node.name is not None:
raise NotImplementedError("'as target' is not supported")
if node.type is not None:
exception_class = self.rm.get(self.obj, self.func_name, node.type)
if not inspect.isclass(exception_class):
raise NotImplementedError("Exception type must be a class")
exception_id = self.rm.exception_map[exception_class]
node.type = ast.copy_location(
ast.Call(func=ast.Name("EncodedException", ast.Load()),
args=[value_to_ast(exception_id)],
keywords=[], starargs=None, kwargs=None),
node.type)
if isinstance(node.type, ast.Tuple):
node.type.elts = [self._encode_exception(e) for e in node.type.elts]
else:
node.type = self._encode_exception(node.type)
self.generic_visit(node)
return node

2 changes: 1 addition & 1 deletion soc/runtime/Makefile
Original file line number Diff line number Diff line change
@@ -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

41 changes: 41 additions & 0 deletions soc/runtime/exception_jmp.S
Original file line number Diff line number Diff line change
@@ -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
5 changes: 3 additions & 2 deletions soc/runtime/exceptions.c
Original file line number Diff line number Diff line change
@@ -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);
}
3 changes: 3 additions & 0 deletions soc/runtime/exceptions.h
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion soc/runtime/main.c
Original file line number Diff line number Diff line change
@@ -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 {
1 change: 1 addition & 0 deletions soc/runtime/services.c
Original file line number Diff line number Diff line change
@@ -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},