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)
{
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. */
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;
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