! 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
! 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
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"
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"}
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)
materialise_stack();
appendir(
new_ir2(
- IR_JUMP, 0,
+ IR_FARJUMP, 0,
new_labelir(helper),
extract_block_refs(bb_get(descriptor->u.lvalue))
)
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
{
ASSERT(0 == 0);
finished();
-}
\ No newline at end of file
+}
--- /dev/null
+#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();
+}
\ No newline at end of file
--- /dev/null
+#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();
+}
\ No newline at end of file
# Flow control --- these never return
V .=i. JUMP
+V .=i. FARJUMP
V .=i. CJUMPEQ
V .=i. CJUMPLT
V .=i. CJUMPLE