lxa now works, I hope; traps are better (and stubbed out on qemuppc).
authorDavid Given <dg@cowlark.com>
Sun, 20 Nov 2016 10:57:21 +0000 (11:57 +0100)
committerDavid Given <dg@cowlark.com>
Sun, 20 Nov 2016 10:57:21 +0000 (11:57 +0100)
mach/proto/mcg/treebuilder.c
plat/qemuppc/libsys/trap.s

index 5462cbf..18e77c9 100644 (file)
@@ -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;
index 09d3b0b..39e5b97 100644 (file)
@@ -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