Made csa and csb work with mcg; adjust the libem functions and the
corresponding invocation in the ncg table so the same helpers can be used for both mcg and ncg. Add a new IR opcode, FARJUMP, which jumps to a helper function but saves volatile registers.
This commit is contained in:
parent
5208e5f751
commit
d31bc6a3f9
|
@ -12,11 +12,14 @@
|
|||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
!
|
||||
! On entry: r3 = address of CSA table
|
||||
! r4 = value
|
||||
! Stack: ( value tableaddr -- )
|
||||
|
||||
.define .csa
|
||||
.csa:
|
||||
lwz r3, 0(sp)
|
||||
lwz r4, 4(sp)
|
||||
addi sp, sp, 8
|
||||
|
||||
lwz r5, 0(r3) ! load default
|
||||
mtspr ctr, r5
|
||||
|
||||
|
|
|
@ -12,11 +12,14 @@
|
|||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
!
|
||||
! On entry: r3 = address of CSB table
|
||||
! r4 = value
|
||||
! Stack: ( value tableaddr -- )
|
||||
|
||||
.define .csb
|
||||
.csb:
|
||||
lwz r3, 0(sp)
|
||||
lwz r4, 4(sp)
|
||||
addi sp, sp, 8
|
||||
|
||||
lwz r5, 0(r3) ! load default
|
||||
mtspr ctr, r5
|
||||
|
||||
|
|
|
@ -466,6 +466,11 @@ PATTERNS
|
|||
emit "b $addr"
|
||||
cost 4;
|
||||
|
||||
FARJUMP(addr:LABEL.I)
|
||||
with corrupted(volatile)
|
||||
emit "b $addr"
|
||||
cost 4;
|
||||
|
||||
JUMP(dest:(int)reg)
|
||||
emit "mtspr ctr, %dest"
|
||||
emit "bcctrl 20, 0, 0"
|
||||
|
|
|
@ -1898,12 +1898,12 @@ PATTERNS
|
|||
addi SP, SP, {CONST, 12}
|
||||
|
||||
pat csa /* Array-lookup switch */
|
||||
with GPR3 GPR4 STACK
|
||||
with STACK
|
||||
gen
|
||||
b {LABEL, ".csa"}
|
||||
|
||||
pat csb /* Table-lookup switch */
|
||||
with GPR3 GPR4 STACK
|
||||
with STACK
|
||||
gen
|
||||
b {LABEL, ".csb"}
|
||||
|
||||
|
|
|
@ -1130,9 +1130,8 @@ static void insn_ivalue(int opcode, arith value)
|
|||
case op_csa:
|
||||
case op_csb:
|
||||
{
|
||||
const char* helper = aprintf(".%s%d",
|
||||
(opcode == op_csa) ? "csa" : "csb",
|
||||
value);
|
||||
const char* helper = aprintf(".%s",
|
||||
(opcode == op_csa) ? "csa" : "csb");
|
||||
struct ir* descriptor = pop(EM_pointersize);
|
||||
|
||||
if (descriptor->opcode != IR_LABEL)
|
||||
|
@ -1143,7 +1142,7 @@ static void insn_ivalue(int opcode, arith value)
|
|||
materialise_stack();
|
||||
appendir(
|
||||
new_ir2(
|
||||
IR_JUMP, 0,
|
||||
IR_FARJUMP, 0,
|
||||
new_labelir(helper),
|
||||
extract_block_refs(bb_get(descriptor->u.lvalue))
|
||||
)
|
||||
|
|
|
@ -33,8 +33,7 @@ var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi
|
|||
name be
|
||||
from .m.g
|
||||
to .s
|
||||
# Change this back to ncg to revert to the old code generator
|
||||
program {EM}/lib/ack/{PLATFORM}/ncg
|
||||
program {EM}/lib/ack/{PLATFORM}/mcg
|
||||
mapflag -gdb GF=-gdb
|
||||
args {GF?} <
|
||||
stdout
|
||||
|
|
|
@ -5,4 +5,4 @@ void _m_a_i_n(void)
|
|||
{
|
||||
ASSERT(0 == 0);
|
||||
finished();
|
||||
}
|
||||
}
|
||||
|
|
26
plat/qemuppc/tests/csa_e.c
Normal file
26
plat/qemuppc/tests/csa_e.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "test.h"
|
||||
|
||||
int csa(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 2: return 2;
|
||||
case 3: return 3;
|
||||
case 4: return 4;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */
|
||||
void _m_a_i_n(void)
|
||||
{
|
||||
ASSERT(csa(0) == 0);
|
||||
ASSERT(csa(1) == 0);
|
||||
ASSERT(csa(2) == 2);
|
||||
ASSERT(csa(3) == 3);
|
||||
ASSERT(csa(4) == 4);
|
||||
ASSERT(csa(5) == 0);
|
||||
ASSERT(csa(6) == 0);
|
||||
|
||||
finished();
|
||||
}
|
26
plat/qemuppc/tests/csb_e.c
Normal file
26
plat/qemuppc/tests/csb_e.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "test.h"
|
||||
|
||||
int csa(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 200: return 200;
|
||||
case 300: return 300;
|
||||
case 400: return 400;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */
|
||||
void _m_a_i_n(void)
|
||||
{
|
||||
ASSERT(csa(0) == 0);
|
||||
ASSERT(csa(100) == 0);
|
||||
ASSERT(csa(200) == 200);
|
||||
ASSERT(csa(300) == 300);
|
||||
ASSERT(csa(400) == 400);
|
||||
ASSERT(csa(500) == 0);
|
||||
ASSERT(csa(600) == 0);
|
||||
|
||||
finished();
|
||||
}
|
|
@ -103,6 +103,7 @@ S ?=i. SETRET
|
|||
|
||||
# Flow control --- these never return
|
||||
V .=i. JUMP
|
||||
V .=i. FARJUMP
|
||||
V .=i. CJUMPEQ
|
||||
V .=i. CJUMPLT
|
||||
V .=i. CJUMPLE
|
||||
|
|
Loading…
Reference in a new issue