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.
|
! address and jumps to it.
|
||||||
! traps if resulting address is zero
|
! traps if resulting address is zero
|
||||||
!
|
!
|
||||||
! On entry: r3 = address of CSA table
|
! Stack: ( value tableaddr -- )
|
||||||
! r4 = value
|
|
||||||
|
|
||||||
.define .csa
|
.define .csa
|
||||||
.csa:
|
.csa:
|
||||||
|
lwz r3, 0(sp)
|
||||||
|
lwz r4, 4(sp)
|
||||||
|
addi sp, sp, 8
|
||||||
|
|
||||||
lwz r5, 0(r3) ! load default
|
lwz r5, 0(r3) ! load default
|
||||||
mtspr ctr, r5
|
mtspr ctr, r5
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,14 @@
|
||||||
! address and jumps to it.
|
! address and jumps to it.
|
||||||
! traps if resulting address is zero
|
! traps if resulting address is zero
|
||||||
!
|
!
|
||||||
! On entry: r3 = address of CSB table
|
! Stack: ( value tableaddr -- )
|
||||||
! r4 = value
|
|
||||||
|
|
||||||
.define .csb
|
.define .csb
|
||||||
.csb:
|
.csb:
|
||||||
|
lwz r3, 0(sp)
|
||||||
|
lwz r4, 4(sp)
|
||||||
|
addi sp, sp, 8
|
||||||
|
|
||||||
lwz r5, 0(r3) ! load default
|
lwz r5, 0(r3) ! load default
|
||||||
mtspr ctr, r5
|
mtspr ctr, r5
|
||||||
|
|
||||||
|
|
|
@ -466,6 +466,11 @@ PATTERNS
|
||||||
emit "b $addr"
|
emit "b $addr"
|
||||||
cost 4;
|
cost 4;
|
||||||
|
|
||||||
|
FARJUMP(addr:LABEL.I)
|
||||||
|
with corrupted(volatile)
|
||||||
|
emit "b $addr"
|
||||||
|
cost 4;
|
||||||
|
|
||||||
JUMP(dest:(int)reg)
|
JUMP(dest:(int)reg)
|
||||||
emit "mtspr ctr, %dest"
|
emit "mtspr ctr, %dest"
|
||||||
emit "bcctrl 20, 0, 0"
|
emit "bcctrl 20, 0, 0"
|
||||||
|
|
|
@ -1898,12 +1898,12 @@ PATTERNS
|
||||||
addi SP, SP, {CONST, 12}
|
addi SP, SP, {CONST, 12}
|
||||||
|
|
||||||
pat csa /* Array-lookup switch */
|
pat csa /* Array-lookup switch */
|
||||||
with GPR3 GPR4 STACK
|
with STACK
|
||||||
gen
|
gen
|
||||||
b {LABEL, ".csa"}
|
b {LABEL, ".csa"}
|
||||||
|
|
||||||
pat csb /* Table-lookup switch */
|
pat csb /* Table-lookup switch */
|
||||||
with GPR3 GPR4 STACK
|
with STACK
|
||||||
gen
|
gen
|
||||||
b {LABEL, ".csb"}
|
b {LABEL, ".csb"}
|
||||||
|
|
||||||
|
|
|
@ -1130,9 +1130,8 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
case op_csa:
|
case op_csa:
|
||||||
case op_csb:
|
case op_csb:
|
||||||
{
|
{
|
||||||
const char* helper = aprintf(".%s%d",
|
const char* helper = aprintf(".%s",
|
||||||
(opcode == op_csa) ? "csa" : "csb",
|
(opcode == op_csa) ? "csa" : "csb");
|
||||||
value);
|
|
||||||
struct ir* descriptor = pop(EM_pointersize);
|
struct ir* descriptor = pop(EM_pointersize);
|
||||||
|
|
||||||
if (descriptor->opcode != IR_LABEL)
|
if (descriptor->opcode != IR_LABEL)
|
||||||
|
@ -1143,7 +1142,7 @@ static void insn_ivalue(int opcode, arith value)
|
||||||
materialise_stack();
|
materialise_stack();
|
||||||
appendir(
|
appendir(
|
||||||
new_ir2(
|
new_ir2(
|
||||||
IR_JUMP, 0,
|
IR_FARJUMP, 0,
|
||||||
new_labelir(helper),
|
new_labelir(helper),
|
||||||
extract_block_refs(bb_get(descriptor->u.lvalue))
|
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
|
name be
|
||||||
from .m.g
|
from .m.g
|
||||||
to .s
|
to .s
|
||||||
# Change this back to ncg to revert to the old code generator
|
program {EM}/lib/ack/{PLATFORM}/mcg
|
||||||
program {EM}/lib/ack/{PLATFORM}/ncg
|
|
||||||
mapflag -gdb GF=-gdb
|
mapflag -gdb GF=-gdb
|
||||||
args {GF?} <
|
args {GF?} <
|
||||||
stdout
|
stdout
|
||||||
|
|
|
@ -5,4 +5,4 @@ void _m_a_i_n(void)
|
||||||
{
|
{
|
||||||
ASSERT(0 == 0);
|
ASSERT(0 == 0);
|
||||||
finished();
|
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
|
# Flow control --- these never return
|
||||||
V .=i. JUMP
|
V .=i. JUMP
|
||||||
|
V .=i. FARJUMP
|
||||||
V .=i. CJUMPEQ
|
V .=i. CJUMPEQ
|
||||||
V .=i. CJUMPLT
|
V .=i. CJUMPLT
|
||||||
V .=i. CJUMPLE
|
V .=i. CJUMPLE
|
||||||
|
|
Loading…
Reference in a new issue