From 196fa914b38f0a8dc53ecee25e9e5a52cf5447f7 Mon Sep 17 00:00:00 2001
From: David Given <dg@cowlark.com>
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   | 64 ++++++++----------------------------
 2 files changed, 39 insertions(+), 56 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:
+	b .trp
+
+.define .trp
+.trp:
+	b .trp					! spin forever
+
+.define .sig
+.sig:
+	lwz r3, 0(sp)
 	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 
-
-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
-
-.sect .rom
-message:
-	.ascii "TRAP!\n"
+	stw r3, 0(r4)
+	bclr ALWAYS, 0, 0		! return
+	
\ No newline at end of file