lxa now works, I hope; traps are better (and stubbed out on qemuppc).
This commit is contained in:
parent
d5328492d7
commit
196fa914b3
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
b .trp
|
||||
|
||||
.define .trap
|
||||
.trap:
|
||||
cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored
|
||||
bc IFTRUE, LT, 1f
|
||||
.define .trp
|
||||
.trp:
|
||||
b .trp ! spin forever
|
||||
|
||||
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:
|
||||
.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
|
||||
stw r3, 0(r4)
|
||||
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"
|
||||
|
|
Loading…
Reference in a new issue