From d31bc6a3f90429d94536174143645fc87c3fc739 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 19 Nov 2016 10:55:41 +0100 Subject: [PATCH] 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. --- mach/powerpc/libem/csa.s | 7 +++++-- mach/powerpc/libem/csb.s | 7 +++++-- mach/powerpc/mcg/table | 5 +++++ mach/powerpc/ncg/table | 4 ++-- mach/proto/mcg/treebuilder.c | 7 +++---- plat/qemuppc/descr | 3 +-- plat/qemuppc/tests/_dummy.c | 2 +- plat/qemuppc/tests/csa_e.c | 26 ++++++++++++++++++++++++++ plat/qemuppc/tests/csb_e.c | 26 ++++++++++++++++++++++++++ util/mcgg/ir.dat | 1 + 10 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 plat/qemuppc/tests/csa_e.c create mode 100644 plat/qemuppc/tests/csb_e.c diff --git a/mach/powerpc/libem/csa.s b/mach/powerpc/libem/csa.s index 64954ff4e..88e6e176a 100644 --- a/mach/powerpc/libem/csa.s +++ b/mach/powerpc/libem/csa.s @@ -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 diff --git a/mach/powerpc/libem/csb.s b/mach/powerpc/libem/csb.s index cbedc8c11..a8df85d7f 100644 --- a/mach/powerpc/libem/csb.s +++ b/mach/powerpc/libem/csb.s @@ -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 diff --git a/mach/powerpc/mcg/table b/mach/powerpc/mcg/table index 03daee94e..79ac7c577 100644 --- a/mach/powerpc/mcg/table +++ b/mach/powerpc/mcg/table @@ -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" diff --git a/mach/powerpc/ncg/table b/mach/powerpc/ncg/table index ed107aceb..6f10c7d4c 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -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"} diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 01e486500..66347447f 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -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)) ) diff --git a/plat/qemuppc/descr b/plat/qemuppc/descr index f28e7482d..c0bc1eab0 100644 --- a/plat/qemuppc/descr +++ b/plat/qemuppc/descr @@ -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 diff --git a/plat/qemuppc/tests/_dummy.c b/plat/qemuppc/tests/_dummy.c index 4a56d8238..48104b5aa 100644 --- a/plat/qemuppc/tests/_dummy.c +++ b/plat/qemuppc/tests/_dummy.c @@ -5,4 +5,4 @@ void _m_a_i_n(void) { ASSERT(0 == 0); finished(); -} \ No newline at end of file +} diff --git a/plat/qemuppc/tests/csa_e.c b/plat/qemuppc/tests/csa_e.c new file mode 100644 index 000000000..355b75ee7 --- /dev/null +++ b/plat/qemuppc/tests/csa_e.c @@ -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(); +} \ No newline at end of file diff --git a/plat/qemuppc/tests/csb_e.c b/plat/qemuppc/tests/csb_e.c new file mode 100644 index 000000000..c86d31fa6 --- /dev/null +++ b/plat/qemuppc/tests/csb_e.c @@ -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(); +} \ No newline at end of file diff --git a/util/mcgg/ir.dat b/util/mcgg/ir.dat index 1db593efc..b34f37fbb 100644 --- a/util/mcgg/ir.dat +++ b/util/mcgg/ir.dat @@ -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