From 196fa914b38f0a8dc53ecee25e9e5a52cf5447f7 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Nov 2016 11:57:21 +0100 Subject: [PATCH] lxa now works, I hope; traps are better (and stubbed out on qemuppc). --- mach/proto/mcg/treebuilder.c | 31 +++++++++++++++--- plat/qemuppc/libsys/trap.s | 62 +++++++----------------------------- 2 files changed, 38 insertions(+), 55 deletions(-) diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 5462cbf79..18e77c94a 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -7,6 +7,7 @@ static struct ir* stack[64]; static struct ir* convert(struct ir* src, int srcsize, int destsize, int opcode); static struct ir* appendir(struct ir* ir); +static void insn_ivalue(int opcode, arith value); static void reset_stack(void) { @@ -486,7 +487,12 @@ static void insn_simple(int opcode) case op_trp: helper_function(".trp"); break; case op_sig: helper_function(".sig"); break; - case op_rtt: helper_function(".rtt"); break; + + case op_rtt: + { + insn_ivalue(op_ret, 0); + break; + } /* FIXME: These instructions are really complex and barely used * (Modula-2 bitset support, I believe). Leave them until later. */ @@ -1202,11 +1208,26 @@ static void insn_ivalue(int opcode, arith value) case op_lxa: { - /* What does this actually *do*? The spec doesn't say. */ - appendir( + struct ir* ir; + + /* Walk the static chain. */ + + ir = new_ir0( + IR_GETFP, EM_pointersize + ); + + while (value--) + { + ir = new_ir1( + IR_CHAINFP, EM_pointersize, + ir + ); + } + + push( new_ir1( - IR_CALL, 0, - new_labelir(".unimplemented_lxa") + IR_FPTOAB, EM_pointersize, + ir ) ); break; diff --git a/plat/qemuppc/libsys/trap.s b/plat/qemuppc/libsys/trap.s index 09d3b0b21..39e5b97ef 100644 --- a/plat/qemuppc/libsys/trap.s +++ b/plat/qemuppc/libsys/trap.s @@ -46,60 +46,22 @@ EBADLIN = 26 EBADGTO = 27 EUNIMPL = 63 ! unimplemented em-instruction called -! EM trap handling. - .define .trap_ecase .trap_ecase: - addi r3, r0, ECASE - b .trap + b .trp .define .trap_earray .trap_earray: - addi r3, r0, EARRAY - b .trap - -.define .trap -.trap: - cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored - bc IFTRUE, LT, 1f - - addi r4, r0, 1 - rlwnm r4, r4, r3, 0, 31 ! calculate trap bit - li32 r5, .ignmask - lwz r5, 0(r5) ! load ignore mask - and. r4, r4, r5 ! compare - bclr IFFALSE, EQ, 0 ! return if non-zero - -1: - li32 r4, .trppc - lwz r5, 0(r4) ! load user trap routine - or. r5, r5, r5 ! test - bc IFTRUE, EQ, fatal ! if no user trap routine, bail out - - addi r0, r0, 0 - stw r0, 0(r4) ! reset trap routine - - mfspr r0, lr - stwu r0, -4(sp) ! save old lr - - stwu r3, -4(sp) - mtspr ctr, r5 - bcctrl ALWAYS, 0, 0 ! call trap routine - - lwz r0, 4(sp) ! load old lr again - addi sp, sp, 8 ! retract over stack usage - bclr ALWAYS, 0, 0 ! return + b .trp -fatal: - addi r3, r0, 1 - li32 r4, message - addi r5, r0, 6 - addi r0, r0, 4 ! write() - sc 0 - - addi r0, r0, 1 ! exit() - sc 0 +.define .trp +.trp: + b .trp ! spin forever -.sect .rom -message: - .ascii "TRAP!\n" +.define .sig +.sig: + lwz r3, 0(sp) + li32 r4, .trppc + stw r3, 0(r4) + bclr ALWAYS, 0, 0 ! return + \ No newline at end of file -- 2.34.1