From 1ea46f6afef4c7db32a07b9c539dfa42dce99857 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 15 Jan 2017 22:26:09 +0100 Subject: [PATCH 01/10] Actually tell the user which tests failed. --- first/testsummary.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/first/testsummary.sh b/first/testsummary.sh index 6c2d3e39a..9ab5daa2f 100755 --- a/first/testsummary.sh +++ b/first/testsummary.sh @@ -26,6 +26,13 @@ echo "$(echo "$timedout" | wc -w) timed out" echo "$(echo "$failed" | wc -w) failed" echo "" +if [ "$failed" != "" ]; then + echo "Failing test logs:" + for t in $failed; do + echo $t + done + exit 1 +fi if [ "$failed" != "" -o "$timedout" != "" ]; then echo "Test status: SAD FACE (tests are failing)" exit 1 From e7e29d34ff53680248f4b733b80bff7a83d2a213 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 15 Jan 2017 22:28:14 +0100 Subject: [PATCH 02/10] Add a test (currently failing) to check that Pascal char sets can store all 256 possible values. Add the PowerPC ncg and mcg backend support to let the test actually run, including modifying a bunch of PowrePC libem functions so that they can be called from both ncg and mcg. --- mach/powerpc/libem/ior.s | 6 +- mach/powerpc/libem/rck.s | 22 ++++ mach/powerpc/libem/set.s | 7 +- mach/powerpc/libem/zer.s | 6 +- mach/powerpc/ncg/table | 58 +++++------ mach/proto/mcg/treebuilder.c | 185 +++++++++++++++++++--------------- plat/linuxppc/libsys/trap.s | 25 +++-- plat/qemuppc/libsys/trap.s | 7 +- tests/plat/charsignedness_p.p | 28 +++++ tests/plat/newdispose_p.p | 4 +- 10 files changed, 218 insertions(+), 130 deletions(-) create mode 100644 mach/powerpc/libem/rck.s create mode 100644 tests/plat/charsignedness_p.p diff --git a/mach/powerpc/libem/ior.s b/mach/powerpc/libem/ior.s index 61e099934..b3ebf81e9 100644 --- a/mach/powerpc/libem/ior.s +++ b/mach/powerpc/libem/ior.s @@ -3,11 +3,13 @@ .sect .text ! Set union. -! Stack: ( b a -- a+b ) -! With r3 = size of set +! Stack: ( size b a -- a+b ) .define .ior .ior: + lwz r3, 0 (sp) + addi sp, sp, 4 + mr r4, sp ! r4 = ptr to set a add r5, sp, r3 ! r5 = ptr to set b rlwinm r6, r3, 30, 2, 31 diff --git a/mach/powerpc/libem/rck.s b/mach/powerpc/libem/rck.s new file mode 100644 index 000000000..b716e5091 --- /dev/null +++ b/mach/powerpc/libem/rck.s @@ -0,0 +1,22 @@ +#include "powerpc.h" + +.sect .text + +! Bounds check. Traps if the value is out of range. +! Stack: ( descriptor value -- ) + +.define .rck +.rck: + lwz r3, 0 (sp) + lwz r4, 4 (sp) + addi sp, sp, 8 + + lwz r5, 0 (r3) + cmp cr0, 0, r4, r5 + bc IFTRUE, LT, .trap_erange + + lwz r5, 4 (r3) + cmp cr0, 0, r4, r5 + bc IFTRUE, GT, .trap_erange + + bclr ALWAYS, 0, 0 diff --git a/mach/powerpc/libem/set.s b/mach/powerpc/libem/set.s index 18ad877e8..daffb9c3d 100644 --- a/mach/powerpc/libem/set.s +++ b/mach/powerpc/libem/set.s @@ -3,11 +3,14 @@ .sect .text ! Create singleton set. -! Stack: ( -- set ) -! With r3 = size of set, r4 = bit number +! Stack: ( size bitnumber -- set ) .define .set .set: + lwz r3, 0 (sp) + lwz r4, 4 (sp) + addi sp, sp, 8 + rlwinm r7, r3, 30, 2, 31 neg r5, r3 add sp, sp, r5 ! allocate set diff --git a/mach/powerpc/libem/zer.s b/mach/powerpc/libem/zer.s index ba978ba3e..697a5715f 100644 --- a/mach/powerpc/libem/zer.s +++ b/mach/powerpc/libem/zer.s @@ -3,11 +3,13 @@ .sect .text ! Create empty set. -! Stack: ( -- set ) -! With r3 = size of set +! Stack: ( size -- set ) .define .zer .zer: + lwz r3, 0(sp) + addi sp, sp, 4 + rlwinm r7, r3, 30, 2, 31 addi r4, r0, 0 ! r4 = zero neg r5, r3 diff --git a/mach/powerpc/ncg/table b/mach/powerpc/ncg/table index 52f335c3d..6498c591c 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -1503,18 +1503,14 @@ PATTERNS yields {OR_RC, %2, lo(%1.val)} pat ior defined($1) /* OR set */ - with STACK - kills ALL - gen - move {CONST, $1}, R3 - bl {LABEL, ".ior"} + leaving + loc $1 + cal ".ior" /* OR set (variable), used in lang/m2/libm2/LtoUset.e */ pat ior !defined($1) - with GPR3 STACK - kills ALL - gen - bl {LABEL, ".ior"} + leaving + cal ".ior" pat xor $1==4 /* XOR word */ with REG REG @@ -1572,12 +1568,10 @@ PATTERNS leaving loc 0 - pat zer defined($1) /* Create empty set */ - with STACK - kills ALL - gen - move {CONST, $1}, R3 - bl {LABEL, ".zer"} + pat zer defined($1) /* Create empty set */ + leaving + loc $1 + cal ".zer" pat sli $1==4 /* Shift left (second << top) */ with CONST_ALL GPR @@ -1655,27 +1649,19 @@ PATTERNS /* Sets */ pat set defined($1) /* Create singleton set */ - with GPR4 STACK - kills ALL - gen - move {CONST, $1}, R3 - bl {LABEL, ".set"} + leaving + loc $1 + cal ".set" /* Create set (variable), used in lang/m2/libm2/LtoUset.e */ pat set !defined($1) - with GPR3 GPR4 STACK - kills ALL - gen - bl {LABEL, ".set"} + leaving + cal ".set" pat inn defined($1) /* Test for set bit */ - with STACK - kills ALL - uses REG - gen - li32 %a, {CONST, $1} - stwu %a, {GPRINDIRECT, SP, 0-4} - bl {LABEL, ".inn"} + leaving + loc $1 + cal ".inn" /* Boolean resolutions */ @@ -2066,6 +2052,16 @@ PATTERNS loc $1 ass 4 + pat lae rck $2==4 /* Range check */ + with GPR + uses CR0 + gen + cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 1)} + bc IFTRUE, LT, {LABEL, ".trap_erange"} + cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 2)} + bc IFTRUE, GT, {LABEL, ".trap_erange"} + + /* Floating point support */ diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 667562e8d..ba4f7198f 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -66,7 +66,7 @@ static struct ir* pop(int size) #if 0 /* If we try to pop something which is smaller than a word, convert it first. */ - + if (size < EM_wordsize) ir = convertu(ir, size); #endif @@ -200,7 +200,7 @@ static struct ir* address_of_external(const char* label, arith offset) static struct ir* convert(struct ir* src, int srcsize, int destsize, int opcode) { - if (srcsize == 1) + if (srcsize == 1) { if ((opcode == IR_FROMSI) || (opcode == IR_FROMSL)) { @@ -433,7 +433,7 @@ static void insn_simple(int opcode) ); break; } - + case op_cii: simple_convert(IR_FROMSI); break; case op_ciu: simple_convert(IR_FROMSI); break; case op_cui: simple_convert(IR_FROMUI); break; @@ -528,10 +528,12 @@ static void insn_simple(int opcode) } /* FIXME: These instructions are really complex and barely used - * (Modula-2 bitset support, I believe). Leave them until later. */ + * (Modula-2 and Pascal set support, I believe). Leave them until + * later. */ case op_set: helper_function(".unimplemented_set"); break; case op_ior: helper_function(".unimplemented_ior"); break; + case op_dch: push( new_ir1( @@ -540,7 +542,7 @@ static void insn_simple(int opcode) ) ); break; - + case op_lpb: push( new_ir1( @@ -607,29 +609,53 @@ static void insn_bvalue(int opcode, struct basicblock* leftbb, struct basicblock } } -static void simple_alu1(int opcode, int size, int irop) +static void simple_alu1(int opcode, int size, int irop, const char* fallback) { - struct ir* val = pop(size); + if (size > (2*EM_wordsize)) + { + if (!fallback) + fatal("treebuilder: can't do opcode %d with size %d", opcode, size); + push( + new_wordir(size) + ); + helper_function(fallback); + } + else + { + struct ir* val = pop(size); - push( - new_ir1( - irop, size, - val - ) - ); + push( + new_ir1( + irop, size, + val + ) + ); + } } -static void simple_alu2(int opcode, int size, int irop) +static void simple_alu2(int opcode, int size, int irop, const char* fallback) { - struct ir* right = pop(size); - struct ir* left = pop(size); + if (size > (2*EM_wordsize)) + { + if (!fallback) + fatal("treebuilder: can't do opcode %d with size %d", opcode, size); + push( + new_wordir(size) + ); + helper_function(fallback); + } + else + { + struct ir* right = pop(size); + struct ir* left = pop(size); - push( - new_ir2( - irop, size, - left, right - ) - ); + push( + new_ir2( + irop, size, + left, right + ) + ); + } } static struct ir* extract_block_refs(struct basicblock* bb) @@ -708,39 +734,43 @@ static void insn_ivalue(int opcode, arith value) { switch (opcode) { - case op_adi: simple_alu2(opcode, value, IR_ADD); break; - case op_sbi: simple_alu2(opcode, value, IR_SUB); break; - case op_mli: simple_alu2(opcode, value, IR_MUL); break; - case op_dvi: simple_alu2(opcode, value, IR_DIV); break; - case op_rmi: simple_alu2(opcode, value, IR_MOD); break; - case op_sli: simple_alu2(opcode, value, IR_ASL); break; - case op_sri: simple_alu2(opcode, value, IR_ASR); break; - case op_ngi: simple_alu1(opcode, value, IR_NEG); break; + case op_adi: simple_alu2(opcode, value, IR_ADD, NULL); break; + case op_sbi: simple_alu2(opcode, value, IR_SUB, NULL); break; + case op_mli: simple_alu2(opcode, value, IR_MUL, NULL); break; + case op_dvi: simple_alu2(opcode, value, IR_DIV, NULL); break; + case op_rmi: simple_alu2(opcode, value, IR_MOD, NULL); break; + case op_sli: simple_alu2(opcode, value, IR_ASL, NULL); break; + case op_sri: simple_alu2(opcode, value, IR_ASR, NULL); break; + case op_ngi: simple_alu1(opcode, value, IR_NEG, NULL); break; - case op_adu: simple_alu2(opcode, value, IR_ADD); break; - case op_sbu: simple_alu2(opcode, value, IR_SUB); break; - case op_mlu: simple_alu2(opcode, value, IR_MUL); break; - case op_slu: simple_alu2(opcode, value, IR_LSL); break; - case op_sru: simple_alu2(opcode, value, IR_LSR); break; - case op_rmu: simple_alu2(opcode, value, IR_MODU); break; - case op_dvu: simple_alu2(opcode, value, IR_DIVU); break; + case op_adu: simple_alu2(opcode, value, IR_ADD, NULL); break; + case op_sbu: simple_alu2(opcode, value, IR_SUB, NULL); break; + case op_mlu: simple_alu2(opcode, value, IR_MUL, NULL); break; + case op_slu: simple_alu2(opcode, value, IR_LSL, NULL); break; + case op_sru: simple_alu2(opcode, value, IR_LSR, NULL); break; + case op_rmu: simple_alu2(opcode, value, IR_MODU, NULL); break; + case op_dvu: simple_alu2(opcode, value, IR_DIVU, NULL); break; - case op_and: simple_alu2(opcode, value, IR_AND); break; - case op_ior: simple_alu2(opcode, value, IR_OR); break; - case op_xor: simple_alu2(opcode, value, IR_EOR); break; - case op_com: simple_alu1(opcode, value, IR_NOT); break; + case op_and: simple_alu2(opcode, value, IR_AND, NULL); break; + case op_ior: simple_alu2(opcode, value, IR_OR, ".ior"); break; + case op_xor: simple_alu2(opcode, value, IR_EOR, NULL); break; + case op_com: simple_alu1(opcode, value, IR_NOT, NULL); break; - case op_adf: simple_alu2(opcode, value, IR_ADDF); break; - case op_sbf: simple_alu2(opcode, value, IR_SUBF); break; - case op_mlf: simple_alu2(opcode, value, IR_MULF); break; - case op_dvf: simple_alu2(opcode, value, IR_DIVF); break; - case op_ngf: simple_alu1(opcode, value, IR_NEGF); break; + case op_adf: simple_alu2(opcode, value, IR_ADDF, NULL); break; + case op_sbf: simple_alu2(opcode, value, IR_SUBF, NULL); break; + case op_mlf: simple_alu2(opcode, value, IR_MULF, NULL); break; + case op_dvf: simple_alu2(opcode, value, IR_DIVF, NULL); break; + case op_ngf: simple_alu1(opcode, value, IR_NEGF, NULL); break; case op_cmu: /* fall through */ case op_cms: push(tristate_compare(value, IR_COMPAREUI)); break; case op_cmi: push(tristate_compare(value, IR_COMPARESI)); break; case op_cmf: push(tristate_compare(value, IR_COMPAREF)); break; + case op_rck: helper_function(".rck"); break; + case op_set: push(new_wordir(value)); helper_function(".set"); break; + case op_inn: push(new_wordir(value)); helper_function(".inn"); break; + case op_lol: push( load( @@ -874,7 +904,7 @@ static void insn_ivalue(int opcode, arith value) ) ); break; - + case op_loc: push( new_wordir(value) @@ -1041,7 +1071,7 @@ static void insn_ivalue(int opcode, arith value) struct ir* right = pop(EM_pointersize); struct ir* left = pop(EM_pointersize); - struct ir* delta = + struct ir* delta = new_ir2( IR_SUB, EM_pointersize, left, right @@ -1053,7 +1083,7 @@ static void insn_ivalue(int opcode, arith value) push(delta); break; } - + case op_dup: { sequence_point(); @@ -1084,6 +1114,18 @@ static void insn_ivalue(int opcode, arith value) break; } + case op_zer: + { + if (value <= EM_wordsize) + push(new_constir(value, 0)); + else + { + push(new_wordir(value)); + helper_function(".zer"); + } + break; + } + case op_asp: { switch (value) @@ -1108,15 +1150,12 @@ static void insn_ivalue(int opcode, arith value) value -= s; } - if (value != 0) - { - appendir( - new_ir1( - IR_STACKADJUST, EM_pointersize, - new_wordir(value) - ) - ); - } + appendir( + new_ir1( + IR_STACKADJUST, EM_pointersize, + new_wordir(value) + ) + ); break; } break; @@ -1169,7 +1208,7 @@ static void insn_ivalue(int opcode, arith value) ); break; } - + case op_lfr: { push( @@ -1300,11 +1339,11 @@ static void insn_ivalue(int opcode, arith value) new_labelir((value == 4) ? ".fef4" : ".fef8") ) ); - + /* exit, leaving an int and then a float (or double) on the stack. */ break; } - + case op_fif: { /* fif is implemented by calling a helper function which then mutates @@ -1320,11 +1359,11 @@ static void insn_ivalue(int opcode, arith value) new_labelir((value == 4) ? ".fif4" : ".fif8") ) ); - + /* exit, leaving two floats (or doubles) on the stack. */ break; } - + case op_lor: { switch (value) @@ -1341,7 +1380,7 @@ static void insn_ivalue(int opcode, arith value) ) ); break; - + case 1: push( appendir( @@ -1492,18 +1531,6 @@ static void insn_ivalue(int opcode, arith value) break; } - /* FIXME: These instructions are really complex and barely used - * (Modula-2 bitset support, I believe). Leave them until leter. */ - case op_inn: - { - push( - new_wordir(value) - ); - - helper_function(".inn"); - break; - } - case op_lin: { /* Set line number --- ignore. */ @@ -1577,7 +1604,7 @@ static void insn_lvalue(int opcode, const char* label, arith offset) ) ); break; - + case op_ine: sequence_point(); appendir( @@ -1666,7 +1693,7 @@ static void insn_lvalue(int opcode, const char* label, arith offset) /* Set filename --- ignore. */ break; } - + default: fatal("treebuilder: unknown lvalue instruction '%s'", em_mnem[opcode - sp_fmnem]); @@ -1699,7 +1726,7 @@ static void generate_tree(struct basicblock* bb) break; case PARAM_LVALUE: - tracef('E', "label=%s offset=%d\n", + tracef('E', "label=%s offset=%d\n", em->u.lvalue.label, em->u.lvalue.offset); insn_lvalue(em->opcode, em->u.lvalue.label, em->u.lvalue.offset); break; diff --git a/plat/linuxppc/libsys/trap.s b/plat/linuxppc/libsys/trap.s index 09d3b0b21..296f17391 100644 --- a/plat/linuxppc/libsys/trap.s +++ b/plat/linuxppc/libsys/trap.s @@ -52,43 +52,48 @@ EUNIMPL = 63 ! unimplemented em-instruction called .trap_ecase: addi r3, r0, ECASE b .trap - + .define .trap_earray .trap_earray: addi r3, r0, EARRAY b .trap - + +.define .trap_erange +.trap_erange: + addi r3, r0, ERANGE + b .trap + .define .trap .trap: cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored bc IFTRUE, LT, 1f - + 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: 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 - bclr ALWAYS, 0, 0 ! return + bclr ALWAYS, 0, 0 ! return fatal: addi r3, r0, 1 @@ -96,7 +101,7 @@ fatal: addi r5, r0, 6 addi r0, r0, 4 ! write() sc 0 - + addi r0, r0, 1 ! exit() sc 0 diff --git a/plat/qemuppc/libsys/trap.s b/plat/qemuppc/libsys/trap.s index f05b907d0..280adc33b 100644 --- a/plat/qemuppc/libsys/trap.s +++ b/plat/qemuppc/libsys/trap.s @@ -49,11 +49,15 @@ EUNIMPL = 63 ! unimplemented em-instruction called .define .trap_ecase .trap_ecase: b .trp - + .define .trap_earray .trap_earray: b .trp +.define .trap_erange +.trap_erange: + b .trap + .define .trp .define .trap .trp: @@ -66,4 +70,3 @@ EUNIMPL = 63 ! unimplemented em-instruction called li32 r4, .trppc stw r3, 0(r4) bclr ALWAYS, 0, 0 ! return - \ No newline at end of file diff --git a/tests/plat/charsignedness_p.p b/tests/plat/charsignedness_p.p new file mode 100644 index 000000000..6263111ce --- /dev/null +++ b/tests/plat/charsignedness_p.p @@ -0,0 +1,28 @@ +# +(*$U+ -- enables underscores in identifiers *) + +program markrelease; + +type + charset = set of char; + +var + s : charset; + i : integer; + +procedure finished; + extern; + +procedure fail(line: integer); + extern; + +#define ASSERT(cond) \ + if (not (cond)) then fail(__LINE__) + +begin + s := []; + for i := 0 to 255 do + s := s + [chr(i)]; + + finished +end. diff --git a/tests/plat/newdispose_p.p b/tests/plat/newdispose_p.p index 36f09e99b..aa3be5a46 100644 --- a/tests/plat/newdispose_p.p +++ b/tests/plat/newdispose_p.p @@ -9,13 +9,13 @@ type var ptr1 : iptr; ptr2 : iptr; - + procedure finished; extern; procedure fail(line: integer); extern; - + #define ASSERT(cond) \ if (not (cond)) then fail(__LINE__) From 5ff983ad9b4b6f01417e7d7df6492595d7b3174c Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 15 Jan 2017 22:30:25 +0100 Subject: [PATCH 03/10] Increase the number of items in a char set from 128 to 256, to cover all possible bytes (7-bit bytes are so 70s). --- lang/pc/comp/type.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/pc/comp/type.c b/lang/pc/comp/type.c index faca8fee5..d13419cf4 100644 --- a/lang/pc/comp/type.c +++ b/lang/pc/comp/type.c @@ -94,8 +94,8 @@ InitTypes() /* character type */ char_type = standard_type(T_CHAR, 1, (arith) 1); - char_type->enm_ncst = 128; /* only 7 bits ASCII characters */ - + char_type->enm_ncst = 256; /* all bytes */ + /* boolean type */ bool_type = standard_type(T_ENUMERATION, 1, (arith) 1); From 5fd1634830b4c43abbc2ca34267d2851b216894c Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 15 Jan 2017 22:33:41 +0100 Subject: [PATCH 04/10] Rename the test to something more sensible. --- tests/plat/{charsignedness_p.p => pascalsets_p.p} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/plat/{charsignedness_p.p => pascalsets_p.p} (94%) diff --git a/tests/plat/charsignedness_p.p b/tests/plat/pascalsets_p.p similarity index 94% rename from tests/plat/charsignedness_p.p rename to tests/plat/pascalsets_p.p index 6263111ce..3253414f9 100644 --- a/tests/plat/charsignedness_p.p +++ b/tests/plat/pascalsets_p.p @@ -1,7 +1,7 @@ # (*$U+ -- enables underscores in identifiers *) -program markrelease; +program pascalsets; type charset = set of char; From b32be06881eee7a075c79fe641c4ac47da536d98 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 15 Jan 2017 22:41:11 +0100 Subject: [PATCH 05/10] Allow the full 8-bit byte range when reading program source. --- lang/pc/comp/LLlex.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/lang/pc/comp/LLlex.c b/lang/pc/comp/LLlex.c index 7bd857a2b..4de2c0d8b 100644 --- a/lang/pc/comp/LLlex.c +++ b/lang/pc/comp/LLlex.c @@ -164,14 +164,10 @@ register int delim; Malloc((unsigned) sizeof(struct string)); register char *p; register int len = ISTRSIZE; - + str->s_str = p = Malloc((unsigned int) ISTRSIZE); for( ; ; ) { LoadChar(ch); - if( ch & 0200 ) { - fatal("non-ascii '\\%03o' read", ch & 0377); - /*NOTREACHED*/ - } if( class(ch) == STNL ) { lexerror("newline in string"); LineNumber++; @@ -310,11 +306,6 @@ again: LoadChar(ch); if( !options['C'] ) /* -C : cases are different */ TO_LOWER(ch); - - if( (ch & 0200) && ch != EOI ) { - fatal("non-ascii '\\%03o' read", ch & 0377); - /*NOTREACHED*/ - } } switch( class(ch) ) { @@ -420,7 +411,7 @@ again: /* dtrg: removed to allow Pascal programs to access system routines * (necessary to make them do anything useful). What's this for, * anyway? */ - + #if 0 if( buf[0] == '_' ) lexerror("underscore starts identifier"); #endif @@ -492,7 +483,7 @@ again: PushBack(); goto end; } - + } if( ch == 'e' || ch == 'E' ) { char *tp = np; /* save position in string */ From 09c79b7dba9660628f16db12b3c6c6831b0f771f Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 15 Jan 2017 23:00:17 +0100 Subject: [PATCH 06/10] Fix cosmetic warning when compiling B. --- lib/descr/fe | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/descr/fe b/lib/descr/fe index 04d33e4fa..b7a07cdc4 100644 --- a/lib/descr/fe +++ b/lib/descr/fe @@ -185,7 +185,7 @@ name b to .k program {EM}/lib/ack/em_b mapflag -B* ABC_F={ABC_F?} -B* - args -i < -o > -w {p} {ABC_F} + args -i < -o > -w {p} {ABC_F?} prep cond rts .b need .b From fa5675d43959b5a4b1f29e28d9796cfc434f3eb6 Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 16 Jan 2017 21:16:33 +0100 Subject: [PATCH 07/10] Run through clang-format. --- mach/proto/ncg/codegen.c | 1750 +++++++++++++++++++++----------------- 1 file changed, 960 insertions(+), 790 deletions(-) diff --git a/mach/proto/ncg/codegen.c b/mach/proto/ncg/codegen.c index 15d99d393..8c7958cf2 100644 --- a/mach/proto/ncg/codegen.c +++ b/mach/proto/ncg/codegen.c @@ -22,12 +22,12 @@ static char rcsid[] = "$Id$"; * Author: Hans van Staveren */ -#define ALLOW_NEXTEM /* code generator is allowed new try of NEXTEM - in exceptional cases */ +#define ALLOW_NEXTEM /* code generator is allowed new try of NEXTEM \ + in exceptional cases */ byte startupcode[] = { DO_NEXTEM }; -byte *nextem(); +byte* nextem(); unsigned costcalc(); unsigned docoerc(); unsigned stackupto(); @@ -38,885 +38,1048 @@ string ad2str(); #define DEBUG(string) #else #include -#define DEBUG(string) {if(Debug) fprintf(stderr,"%-*d%s\n",4*level,level,string);} +#define DEBUG(string) \ + { \ + if (Debug) \ + fprintf(stderr, "%-*d%s\n", 4 * level, level, string); \ + } #endif -#define BROKE() {assert(origcp!=startupcode || !paniced);DEBUG("BROKE");totalcost=INFINITY;goto doreturn;} -#define CHKCOST() {if (totalcost>=costlimit) BROKE();} +#define BROKE() \ + { \ + assert(origcp != startupcode || !paniced); \ + DEBUG("BROKE"); \ + totalcost = INFINITY; \ + goto doreturn; \ + } +#define CHKCOST() \ + { \ + if (totalcost >= costlimit) \ + BROKE(); \ + } #ifdef TABLEDEBUG int tablelines[MAXTDBUG]; int ntableline; -int set_fd,set_size; -short *set_val; -char *set_flag; +int set_fd, set_size; +short* set_val; +char* set_flag; #endif -unsigned codegen(codep,ply,toplevel,costlimit,forced) byte *codep; unsigned costlimit; { +unsigned codegen(codep, ply, toplevel, costlimit, forced) byte* codep; +unsigned costlimit; +{ #ifndef NDEBUG - byte *origcp=codep; - static int level=0; + byte* origcp = codep; + static int level = 0; #endif unsigned totalcost = 0; - int inscoerc=0; - int procarg[MAXPROCARG+1]; + int inscoerc = 0; + int procarg[MAXPROCARG + 1]; #ifdef ALLOW_NEXTEM static int paniced; - char *savebp = 0; + char* savebp = 0; #endif state_t state; -#define SAVEST savestatus(&state) -#define RESTST restorestatus(&state) -#define FREEST /* nothing */ +#define SAVEST savestatus(&state) +#define RESTST restorestatus(&state) +#define FREEST /* nothing */ #ifdef TABLEDEBUG - extern char *tablename; + extern char* tablename; #endif #ifndef NDEBUG assert(costlimit <= INFINITY); level++; DEBUG("Entering codegen"); - if (Debug > 1) fprintf(stderr, "toplevel = %d\n", toplevel); + if (Debug > 1) + fprintf(stderr, "toplevel = %d\n", toplevel); #endif - for (;;) { - switch( (*codep++)&037 ) { - default: - assert(FALSE); - /* NOTREACHED */ + for (;;) + { + switch ((*codep++) & 037) + { + default: + assert(FALSE); +/* NOTREACHED */ #ifdef TABLEDEBUG - case DO_DLINE: { - int n; + case DO_DLINE: + { + int n; - getint(n,codep); - tablelines[ntableline++] = n; - if (ntableline>=MAXTDBUG) - ntableline -= MAXTDBUG; - if (set_fd) - set_val[n>>4] &= ~(1<<(n&017)); + getint(n, codep); + tablelines[ntableline++] = n; + if (ntableline >= MAXTDBUG) + ntableline -= MAXTDBUG; + if (set_fd) + set_val[n >> 4] &= ~(1 << (n & 017)); #ifndef NDEBUG - if (Debug) - fprintf(stderr,"code from \"%s\", line %d\n",tablename,n); + if (Debug) + fprintf(stderr, "code from \"%s\", line %d\n", tablename, n); #endif - break; - } + break; + } #endif - case DO_NEXTEM: { - byte *bp; - int n; - unsigned mindistance,dist; - register i; - int cindex; - int npos,pos[MAXRULE]; - unsigned mincost,t; + case DO_NEXTEM: + { + byte* bp; + int n; + unsigned mindistance, dist; + register i; + int cindex; + int npos, pos[MAXRULE]; + unsigned mincost, t; - DEBUG("NEXTEM"); - tokpatlen = 0; - nallreg=0; - if (toplevel) { - garbage_collect(); - totalcost=0; - } else { - if (--ply <= 0) - goto doreturn; - } - if (stackheight>MAXFSTACK-7) { + DEBUG("NEXTEM"); + tokpatlen = 0; + nallreg = 0; + if (toplevel) + { + garbage_collect(); + totalcost = 0; + } + else + { + if (--ply <= 0) + goto doreturn; + } + if (stackheight > MAXFSTACK - 7) + { #ifndef NDEBUG - if (Debug) - fprintf(stderr,"Fakestack overflow threatens(%d), action ...\n",stackheight); + if (Debug) + fprintf(stderr, "Fakestack overflow threatens(%d), action ...\n", stackheight); #endif - totalcost += stackupto(&fakestack[6],ply,toplevel); - } + totalcost += stackupto(&fakestack[6], ply, toplevel); + } #ifndef ALLOW_NEXTEM - bp = nextem(toplevel); + bp = nextem(toplevel); #else - if (toplevel) paniced=0; - savebp = nextem(toplevel); - panic: - if (toplevel) totalcost = 0; - bp = savebp; + if (toplevel) + paniced = 0; + savebp = nextem(toplevel); + panic: + if (toplevel) + totalcost = 0; + bp = savebp; #endif - if (bp == 0) { - /* + if (bp == 0) + { + /* * No pattern found, can be pseudo or error * in table. */ - if (toplevel) { - codep--; - DEBUG("pseudo"); - dopseudo(); - } else - goto doreturn; - } else { -#ifndef NDEBUG - chkregs(); -#endif - if (! toplevel) { - ply -= emp-saveemp+1; - if (ply <= 0) ply = 1; - } - n = *bp++; - if (n==0) { /* "procedure" */ - int j, nargs; - getint(i,bp); - getint(nargs,bp); - assert(nargs <= MAXPROCARG); - for (j = 0; j < nargs; j++) { - getint(procarg[j],bp); - } - bp= &pattern[i]; - n = *bp++; - DEBUG("PROC_CALL"); - } - assert(n>0 && n<=MAXRULE); - if (n>1) { - mindistance = MAXINT; npos=0; - for(i=0;i1) { - /* + else + { +#ifndef NDEBUG + chkregs(); +#endif + if (!toplevel) + { + ply -= emp - saveemp + 1; + if (ply <= 0) + ply = 1; + } + n = *bp++; + if (n == 0) + { /* "procedure" */ + int j, nargs; + getint(i, bp); + getint(nargs, bp); + assert(nargs <= MAXPROCARG); + for (j = 0; j < nargs; j++) + { + getint(procarg[j], bp); + } + bp = &pattern[i]; + n = *bp++; + DEBUG("PROC_CALL"); + } + assert(n > 0 && n <= MAXRULE); + if (n > 1) + { + mindistance = MAXINT; + npos = 0; + for (i = 0; i < n; i++) + { + getint(cindex, bp); + dist = distance(cindex); +#ifndef NDEBUG + if (Debug) + fprintf(stderr, "distance of pos %d is %u\n", i, dist); +#endif + if (dist <= mindistance +#ifdef ALLOW_NEXTEM + || paniced +#endif + ) + { + if (dist < mindistance) + { + if (dist == 0) + goto gotit; + npos = 0; + mindistance = dist; + } +#ifdef ALLOW_NEXTEM + if (dist < MAXINT) +#endif + pos[npos++] = cindex; + } + } + assert(mindistance < MAXINT); + if (npos > 1) + { + /* * More than 1 tokenpattern is a candidate. * Decision has to be made by lookahead. */ - SAVEST; - mincost = costlimit-totalcost+1; - assert(mincost <= INFINITY); - for(i=0;i costlimit) + { + BROKE(); + } + } + else + { + cindex = pos[0]; + } + } + else + { + getint(cindex, bp); } - RESTST; - } - FREEST; - if (totalcost+mincost>costlimit) { - BROKE(); - } - } else { - cindex = pos[0]; - } - } else { - getint(cindex,bp); - } - gotit: - /* + gotit: + /* * Now cindex contains the code-index of the best candidate * so proceed to use it. */ - codep = &coderules[cindex]; - } - break; - } - case DO_COERC: { - DEBUG("COERC"); - tokpatlen=1; - inscoerc=1; - break; - } - case DO_XXMATCH: - DEBUG("XXMATCH"); - case DO_XMATCH: { - register i; - int temp; - - DEBUG("XMATCH"); - tokpatlen=(codep[-1]>>5)&07; - for (i=0;i>5)&07; - for(i=0;i=fakestack) { - size=tsize(tp); - while (i= fakestack) { - size = tsize(tp); - lsize= ssize(tokexp[i]); - if (size != lsize) { /* find coercion */ -#ifdef MAXSPLIT - sret = split(tp,&tokexp[i],ply,toplevel); - if (sret==0) { -#endif /* MAXSPLIT */ - totalcost += stackupto(tp,ply,toplevel); - CHKCOST(); - break; -#ifdef MAXSPLIT - } - i += sret; -#endif /* MAXSPLIT */ - } else - i += 1; - tp--; - } - nextmatch: - tp = &fakestack[stackheight-1]; - i=0; nregneeded = 0; - while (i=fakestack) { - if (!match(tp,&machsets[tokexp[i]],0)) { - cp = findcoerc(tp, &machsets[tokexp[i]]); -#ifndef NDEBUG -if (Debug>1) fprintf(stderr,"findcoerc returns 0x%x at position %d\n",(unsigned)cp,i); -#endif - if (cp==0) { - for (j=0;jc3_prop<0) { - totalcost+=docoerc(tp,cp,ply,toplevel,0); - CHKCOST(); - } else { -#ifndef NDEBUG -if(Debug>1) fprintf(stderr,"Register of type %d needed, remembering...\n",cp->c3_prop); -#endif - assert(nregneededstackheight) { -#ifndef NDEBUG -if(Debug>1) fprintf(stderr,"Pattern too long, %d with only %d items on stack\n", - tokpatlen,stackheight); + case DO_COERC: + { + DEBUG("COERC"); + tokpatlen = 1; + inscoerc = 1; + break; + } + case DO_XXMATCH: + DEBUG("XXMATCH"); + case DO_XMATCH: + { + register i; + int temp; + + DEBUG("XMATCH"); + tokpatlen = (codep[-1] >> 5) & 07; + for (i = 0; i < tokpatlen; i++) + getint(temp, codep); + break; /* match already checked by distance() */ + } + case DO_MATCH: + { + register i; + int j; + unsigned mincost, t; + token_p tp; + int size, lsize; + int tokexp[MAXPATLEN]; + int nregneeded; + token_p regtp[MAXCREG]; + c3_p regcp[MAXCREG]; + rl_p regls[MAXCREG]; + c3_p cp, findcoerc(); +#ifdef MAXSPLIT + int sret; #endif - stackpad = tokpatlen-stackheight; - for (j=stackheight-1;j>=0;j--) - fakestack[j+stackpad] = fakestack[j]; - for (j=0;j=fakestack;i++,tp--) { - cp = findcoerc((token_p) 0, &machsets[tokexp[i]]); - if (cp==0) { - for (j=0;j> 5) & 07; + for (i = 0; i < tokpatlen; i++) + getint(tokexp[i], codep); + tokexp[i] = 0; + tp = &fakestack[stackheight - 1]; + i = 0; + while (i < tokpatlen && tp >= fakestack) + { + size = tsize(tp); + while (i < tokpatlen && (lsize = ssize(tokexp[i])) <= size) + { + size -= lsize; + i++; + } + if (i < tokpatlen && size != 0) + { + totalcost += stackupto(tp, ply, toplevel); + CHKCOST(); + break; + } + tp--; + } + tp = &fakestack[stackheight - 1]; + i = 0; + while (i < tokpatlen && tp >= fakestack) + { + size = tsize(tp); + lsize = ssize(tokexp[i]); + if (size != lsize) + { /* find coercion */ +#ifdef MAXSPLIT + sret = split(tp, &tokexp[i], ply, toplevel); + if (sret == 0) + { +#endif /* MAXSPLIT */ + totalcost += stackupto(tp, ply, toplevel); + CHKCOST(); + break; +#ifdef MAXSPLIT + } + i += sret; +#endif /* MAXSPLIT */ + } + else + i += 1; + tp--; + } + nextmatch: + tp = &fakestack[stackheight - 1]; + i = 0; + nregneeded = 0; + while (i < tokpatlen && tp >= fakestack) + { + if (!match(tp, &machsets[tokexp[i]], 0)) + { + cp = findcoerc(tp, &machsets[tokexp[i]]); +#ifndef NDEBUG + if (Debug > 1) + fprintf(stderr, "findcoerc returns 0x%x at position %d\n", (unsigned)cp, i); +#endif + if (cp == 0) + { + for (j = 0; j < nregneeded; j++) + regtp[j] -= (tp - fakestack + 1); + totalcost += stackupto(tp, ply, toplevel); + CHKCOST(); + break; + } + else + { + if (cp->c3_prop < 0) + { + totalcost += docoerc(tp, cp, ply, toplevel, 0); + CHKCOST(); + } + else + { +#ifndef NDEBUG + if (Debug > 1) + fprintf(stderr, "Register of type %d needed, remembering...\n", cp->c3_prop); +#endif + assert(nregneeded < MAXCREG); + regtp[nregneeded] = tp; + regcp[nregneeded] = cp; + regls[nregneeded] = curreglist; + nregneeded++; + } + } + } + i++; + tp--; + } + if (tokpatlen > stackheight) + { +#ifndef NDEBUG + if (Debug > 1) + fprintf(stderr, "Pattern too long, %d with only %d items on stack\n", + tokpatlen, stackheight); +#endif + stackpad = tokpatlen - stackheight; + for (j = stackheight - 1; j >= 0; j--) + fakestack[j + stackpad] = fakestack[j]; + for (j = 0; j < stackpad; j++) + fakestack[j].t_token = 0; + stackheight += stackpad; + for (j = 0; j < nregneeded; j++) + regtp[j] += stackpad; + for (tp = &fakestack[stackpad - 1]; i < tokpatlen && tp >= fakestack; i++, tp--) + { + cp = findcoerc((token_p)0, &machsets[tokexp[i]]); + if (cp == 0) + { + for (j = 0; j < nregneeded; j++) + myfree((string)(regls[j])); #ifndef ALLOW_NEXTEM - assert(!toplevel); - BROKE(); + assert(!toplevel); + BROKE(); #else - assert(!(toplevel&&paniced)); - if (paniced) goto normalfailed; - totalcost = INFINITY; - for (i=0;ic3_prop<0) { - totalcost+=docoerc(tp,cp,ply,toplevel,0); - CHKCOST(); - } else { - assert(nregneededc3_prop < 0) + { + totalcost += docoerc(tp, cp, ply, toplevel, 0); + CHKCOST(); + } + else + { + assert(nregneeded < MAXCREG); + regtp[nregneeded] = tp; + regcp[nregneeded] = cp; + regls[nregneeded] = curreglist; + nregneeded++; + } + } + } + else + stackpad = 0; + assert(i == tokpatlen); + if (nregneeded == 0) + break; + SAVEST; + mincost = costlimit - totalcost + 1; + tup = tuples(regls, nregneeded); + besttup = 0; + for (; tup != 0; tup = ntup) + { #ifndef NDEBUG -if(Debug>1) { fprintf(stderr,"Next tuple %d,%d,%d,%d\n", - tup->p_rar[0], - tup->p_rar[1], - tup->p_rar[2], - tup->p_rar[3]); - fprintf(stderr, "totalcost = %u, costlimit = %u, mincost = %u\n", - totalcost, costlimit, mincost); - } + if (Debug > 1) + { + fprintf(stderr, "Next tuple %d,%d,%d,%d\n", + tup->p_rar[0], + tup->p_rar[1], + tup->p_rar[2], + tup->p_rar[3]); + fprintf(stderr, "totalcost = %u, costlimit = %u, mincost = %u\n", + totalcost, costlimit, mincost); + } #endif - ntup = tup->p_next; - for (i=0,t=0;ip_rar[i]); + ntup = tup->p_next; + for (i = 0, t = 0; i < nregneeded && t < mincost; i++) + t += docoerc(regtp[i], regcp[i], ply, FALSE, tup->p_rar[i]); #ifndef NDEBUG -if (Debug > 1) fprintf(stderr, "cost after coercions: %u\n", t); + if (Debug > 1) + fprintf(stderr, "cost after coercions: %u\n", t); #endif - if ( t2) - fprintf(stderr,"Continuing match after coercions\n"); + if (Debug > 2) + fprintf(stderr, "Continuing match after coercions\n"); #endif - t += codegen(codep,ply,FALSE,mincostcostlimit) { - if (besttup) - myfree((string)besttup); -normalfailed: if (stackpad!=tokpatlen) { - if (stackpad) { - for (i=0;i costlimit) + { + if (besttup) + myfree((string)besttup); + normalfailed: + if (stackpad != tokpatlen) + { + if (stackpad) + { + for (i = 0; i < stackheight - stackpad; i++) + fakestack[i] = fakestack[i + stackpad]; + stackheight -= stackpad; + if (costlimit < MAXINT) + BROKE(); + totalcost += stackupto(&fakestack[stackheight - 1], ply, toplevel); + } + else + totalcost += stackupto(fakestack, ply, toplevel); + CHKCOST(); + goto nextmatch; + } + totalcost += mincost; + for (i = 0; i < stackheight - stackpad; i++) + fakestack[i] = fakestack[i + stackpad]; + stackheight -= stackpad; BROKE(); - totalcost += stackupto(&fakestack[stackheight-1],ply,toplevel); - } else - totalcost += stackupto(fakestack,ply,toplevel); - CHKCOST(); - goto nextmatch; - } - totalcost += mincost; - for (i=0;ip_rar[i]); - assert(totalcost <= costlimit); - myfree((string)besttup); - break; - } - case DO_TOSTACK: - case DO_REMOVE: { - int texpno,nodeno; - token_p tp; - struct reginfo *rp; - int doremove = (codep[-1] & 037) == DO_REMOVE; - extern int allsetno; + } + for (i = 0; i < nregneeded; i++) + totalcost += docoerc(regtp[i], regcp[i], ply, toplevel, besttup->p_rar[i]); + assert(totalcost <= costlimit); + myfree((string)besttup); + break; + } + case DO_TOSTACK: + case DO_REMOVE: + { + int texpno, nodeno; + token_p tp; + struct reginfo* rp; + int doremove = (codep[-1] & 037) == DO_REMOVE; + extern int allsetno; - DEBUG(doremove ? "REMOVE" : "TOSTACK"); - if (codep[-1]&32) { - getint(texpno,codep); - getint(nodeno,codep); - } else { - getint(texpno,codep); - nodeno=0; - } - if (texpno == allsetno) { - totalcost += stackupto(&fakestack[stackheight-tokpatlen-1],ply,toplevel); - CHKCOST(); - if (doremove) for (rp=machregs;rpr_contents.t_token=0; - break; - } - for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--) - if (match(tp,&machsets[texpno],nodeno)) { - /* investigate possible coercion to register */ - totalcost += stackupto(tp,ply,toplevel); - CHKCOST(); - break; - } - if (doremove) for (rp=machregs;rpr_contents.t_token != 0 && - match(&rp->r_contents,&machsets[texpno],nodeno)) { + DEBUG(doremove ? "REMOVE" : "TOSTACK"); + if (codep[-1] & 32) + { + getint(texpno, codep); + getint(nodeno, codep); + } + else + { + getint(texpno, codep); + nodeno = 0; + } + if (texpno == allsetno) + { + totalcost += stackupto(&fakestack[stackheight - tokpatlen - 1], ply, toplevel); + CHKCOST(); + if (doremove) + for (rp = machregs; rp < machregs + NREGS; rp++) + rp->r_contents.t_token = 0; + break; + } + for (tp = &fakestack[stackheight - tokpatlen - 1]; tp >= &fakestack[0]; tp--) + if (match(tp, &machsets[texpno], nodeno)) + { + /* investigate possible coercion to register */ + totalcost += stackupto(tp, ply, toplevel); + CHKCOST(); + break; + } + if (doremove) + for (rp = machregs; rp < machregs + NREGS; rp++) + { + if (rp->r_contents.t_token != 0 && match(&rp->r_contents, &machsets[texpno], nodeno)) + { #ifndef NDEBUG - if (Debug > 1) fprintf(stderr, "killing reg %ld (%s)\n", (long)(rp-machregs), rp->r_repr ? codestrings[rp->r_repr] : "cc"); + if (Debug > 1) + fprintf(stderr, "killing reg %ld (%s)\n", (long)(rp - machregs), rp->r_repr ? codestrings[rp->r_repr] : "cc"); #endif - rp->r_contents.t_token=0; - } - } - break; - } - case DO_KILLREG: - case DO_RREMOVE: { /* register remove */ - register i; - int nodeno; - token_p tp; - tkdef_p tdp; - result_t result; - int dokill = (codep[-1] & 037) == DO_KILLREG; + rp->r_contents.t_token = 0; + } + } + break; + } + case DO_KILLREG: + case DO_RREMOVE: + { /* register remove */ + register i; + int nodeno; + token_p tp; + tkdef_p tdp; + result_t result; + int dokill = (codep[-1] & 037) == DO_KILLREG; - DEBUG(dokill ? "KILLREG" : "RREMOVE"); - getint(nodeno,codep); - compute(&enodes[nodeno], &result); - if (result.e_typ!=EV_REG) - break; - if ( in_stack(result.e_v.e_reg) ) BROKE() ; /* Check aside-stack */ - if (dokill) { - /* kill register, and kill condition codes if they are set to + DEBUG(dokill ? "KILLREG" : "RREMOVE"); + getint(nodeno, codep); + compute(&enodes[nodeno], &result); + if (result.e_typ != EV_REG) + break; + if (in_stack(result.e_v.e_reg)) + BROKE(); /* Check aside-stack */ + if (dokill) + { + /* kill register, and kill condition codes if they are set to this register */ - machregs[result.e_v.e_reg].r_contents.t_token = 0; - if (machregs[0].r_contents.t_token == -1 && - machregs[0].r_contents.t_att[0].ar == result.e_v.e_reg) { - machregs[0].r_contents.t_token = 0; - } - } - for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--) - if (tp->t_token==-1) { - if(tp->t_att[0].ar==result.e_v.e_reg) - goto gotone; - } else { - tdp = &tokens[tp->t_token]; - for(i=0;it_type[i]==EV_REG && - tp->t_att[i].ar==result.e_v.e_reg) - goto gotone; - } - break; - gotone: - /* investigate possible coercion to register */ - totalcost += stackupto(tp,ply,toplevel); - CHKCOST(); - break; - } - case DO_DEALLOCATE: { - register i; - tkdef_p tdp; - int tinstno; - token_t token; - - DEBUG("DEALLOCATE"); - getint(tinstno,codep); - instance(tinstno,&token); - if (token.t_token==-1) - chrefcount(token.t_att[0].ar,-1,TRUE); - else { - tdp= &tokens[token.t_token]; - for (i=0;it_type[i]==EV_REG) - chrefcount(token.t_att[i].ar,-1,TRUE); - } - break; - } - case DO_REALLOCATE: { - struct reginfo *rp; - - DEBUG("REALLOCATE"); - for(rp=machregs+1;rpr_tcount) { - rp->r_refcount -= rp->r_tcount; - rp->r_tcount = 0; - } - break; - } - case DO_ALLOCATE: { - register i; - int j; - int tinstno; - int npos,npos2,pos[NREGS],pos2[NREGS]; - unsigned mincost,t; - struct reginfo *rp,**rpp; - token_t token,token2; - int propno; - int exactmatch; - int decision; - - if (codep[-1]&32) { - getint(propno,codep); - getint(tinstno,codep); - DEBUG("ALLOCATE,INIT"); - } else { - getint(propno,codep); - tinstno=0; - DEBUG("ALLOCATE,EMPTY"); - } - instance(tinstno,&token); - if (!forced) { - do { - npos=exactmatch=0; - for(rpp=reglist[propno];rp= *rpp; rpp++) - if (getrefcount((int)(rp-machregs), FALSE)==0) { - pos[npos++] = rp-machregs; - if (eqtoken(&rp->r_contents,&token)) - pos2[exactmatch++] = rp-machregs; + machregs[result.e_v.e_reg].r_contents.t_token = 0; + if (machregs[0].r_contents.t_token == -1 && machregs[0].r_contents.t_att[0].ar == result.e_v.e_reg) + { + machregs[0].r_contents.t_token = 0; + } } - /* + for (tp = &fakestack[stackheight - tokpatlen - 1]; tp >= &fakestack[0]; tp--) + if (tp->t_token == -1) + { + if (tp->t_att[0].ar == result.e_v.e_reg) + goto gotone; + } + else + { + tdp = &tokens[tp->t_token]; + for (i = 0; i < TOKENSIZE; i++) + if (tdp->t_type[i] == EV_REG && tp->t_att[i].ar == result.e_v.e_reg) + goto gotone; + } + break; + gotone: + /* investigate possible coercion to register */ + totalcost += stackupto(tp, ply, toplevel); + CHKCOST(); + break; + } + case DO_DEALLOCATE: + { + register i; + tkdef_p tdp; + int tinstno; + token_t token; + + DEBUG("DEALLOCATE"); + getint(tinstno, codep); + instance(tinstno, &token); + if (token.t_token == -1) + chrefcount(token.t_att[0].ar, -1, TRUE); + else + { + tdp = &tokens[token.t_token]; + for (i = 0; i < TOKENSIZE; i++) + if (tdp->t_type[i] == EV_REG) + chrefcount(token.t_att[i].ar, -1, TRUE); + } + break; + } + case DO_REALLOCATE: + { + struct reginfo* rp; + + DEBUG("REALLOCATE"); + for (rp = machregs + 1; rp < machregs + NREGS; rp++) + if (rp->r_tcount) + { + rp->r_refcount -= rp->r_tcount; + rp->r_tcount = 0; + } + break; + } + case DO_ALLOCATE: + { + register i; + int j; + int tinstno; + int npos, npos2, pos[NREGS], pos2[NREGS]; + unsigned mincost, t; + struct reginfo *rp, **rpp; + token_t token, token2; + int propno; + int exactmatch; + int decision; + + if (codep[-1] & 32) + { + getint(propno, codep); + getint(tinstno, codep); + DEBUG("ALLOCATE,INIT"); + } + else + { + getint(propno, codep); + tinstno = 0; + DEBUG("ALLOCATE,EMPTY"); + } + instance(tinstno, &token); + if (!forced) + { + do + { + npos = exactmatch = 0; + for (rpp = reglist[propno]; rp = *rpp; rpp++) + if (getrefcount((int)(rp - machregs), FALSE) == 0) + { + pos[npos++] = rp - machregs; + if (eqtoken(&rp->r_contents, &token)) + pos2[exactmatch++] = rp - machregs; + } + /* * Now pos[] contains all free registers with desired * property. If none then some stacking has to take place. */ - if (npos==0) { - if (stackheight<=tokpatlen) { - if (!toplevel) { - BROKE(); - } else { - if (paniced) - fatal("No regs available"); - totalcost += stackupto( &fakestack[0],ply,toplevel); - goto panic; - } - } - totalcost += stackupto( &fakestack[0],ply,toplevel); - CHKCOST(); - } - } while (npos==0); + if (npos == 0) + { + if (stackheight <= tokpatlen) + { + if (!toplevel) + { + BROKE(); + } + else + { + if (paniced) + fatal("No regs available"); + totalcost += stackupto(&fakestack[0], ply, toplevel); + goto panic; + } + } + totalcost += stackupto(&fakestack[0], ply, toplevel); + CHKCOST(); + } + } while (npos == 0); - if (!exactmatch && tinstno!=0) { - /* + if (!exactmatch && tinstno != 0) + { + /* * No exact match, but we were looking for a particular * token. Now try to find registers of which no * known contents is available (the others might still * be useful). */ - for (i=0;i costlimit) + BROKE(); + } + } + else + { + decision = forced; + if (getrefcount(decision, FALSE) != 0) + BROKE(); + token2.t_token = -1; + } + chrefcount(decision, 1, FALSE); + token2.t_att[0].ar = decision; if (token.t_token != 0) - t=move(&token,&token2,ply,FALSE,mincost); - else { - t = 0; - erasereg(pos2[j]); + { + totalcost += move(&token, &token2, ply, toplevel, MAXINT); + CHKCOST(); } - if (tcostlimit) - BROKE(); - } - } else { - decision = forced; - if (getrefcount(decision, FALSE)!=0) - BROKE(); - token2.t_token = -1; - } - chrefcount(decision,1,FALSE); - token2.t_att[0].ar=decision; - if (token.t_token != 0) { - totalcost+=move(&token,&token2,ply,toplevel,MAXINT); - CHKCOST(); - } else - erasereg(decision); - allreg[nallreg++]=decision; - break; - } - case DO_INSTR: { - register i; - int n; - int tinstno; - token_t token; - int stringno; + case DO_INSTR: + { + register i; + int n; + int tinstno; + token_t token; + int stringno; - DEBUG("INSTR"); - n=((codep[-1]>>5)&07); - getint(stringno,codep); - if (toplevel) { - swtxt(); - if (stringno>10000) { - assert(stringno < 100001 + MAXPROCARG); - genstr(procarg[stringno-10001]); - } else - genstr(stringno); - } - for(i=0;i0) - totalcost += tokens[token.t_token].t_cost.ct_space; - } - if (toplevel) - gennl(); - CHKCOST(); - break; - } - case DO_MOVE: { - int tinstno; - token_t token,token2; + DEBUG("INSTR"); + n = ((codep[-1] >> 5) & 07); + getint(stringno, codep); + if (toplevel) + { + swtxt(); + if (stringno > 10000) + { + assert(stringno < 100001 + MAXPROCARG); + genstr(procarg[stringno - 10001]); + } + else + genstr(stringno); + } + for (i = 0; i < n; i++) + { + getint(tinstno, codep); + instance(tinstno, &token); + if (toplevel) + prtoken(&token, i == 0 ? ' ' : ','); + if (token.t_token > 0) + totalcost += tokens[token.t_token].t_cost.ct_space; + } + if (toplevel) + gennl(); + CHKCOST(); + break; + } + case DO_MOVE: + { + int tinstno; + token_t token, token2; - DEBUG("MOVE"); - getint(tinstno,codep); - instance(tinstno,&token); - getint(tinstno,codep); - instance(tinstno,&token2); - totalcost += move(&token,&token2,ply,toplevel,costlimit-totalcost+1); - CHKCOST(); - break; - } - case DO_TEST: { - int tinstno; - token_t token; + DEBUG("MOVE"); + getint(tinstno, codep); + instance(tinstno, &token); + getint(tinstno, codep); + instance(tinstno, &token2); + totalcost += move(&token, &token2, ply, toplevel, costlimit - totalcost + 1); + CHKCOST(); + break; + } + case DO_TEST: + { + int tinstno; + token_t token; - DEBUG("TEST"); - getint(tinstno,codep); - instance(tinstno,&token); - totalcost += test(&token,ply,toplevel,costlimit-totalcost+1); - CHKCOST(); - break; - } - case DO_SETCC: { - int tinstno; - token_t token; + DEBUG("TEST"); + getint(tinstno, codep); + instance(tinstno, &token); + totalcost += test(&token, ply, toplevel, costlimit - totalcost + 1); + CHKCOST(); + break; + } + case DO_SETCC: + { + int tinstno; + token_t token; - DEBUG("SETCC"); - getint(tinstno,codep); - instance(tinstno,&token); - setcc(&token); - break; - } - case DO_ERASE: { - int nodeno; - result_t result; + DEBUG("SETCC"); + getint(tinstno, codep); + instance(tinstno, &token); + setcc(&token); + break; + } + case DO_ERASE: + { + int nodeno; + result_t result; - DEBUG("ERASE"); - getint(nodeno,codep); - compute(&enodes[nodeno], &result); - assert(result.e_typ!=EV_INT && result.e_typ!=EV_ADDR); - if (result.e_typ==EV_REG) - { - int regno = result.e_v.e_reg; - erasereg(regno); - } - break; - } - case DO_TOKREPLACE: { - register i; - int tinstno; - int repllen; - token_t reptoken[MAXREPLLEN]; + DEBUG("ERASE"); + getint(nodeno, codep); + compute(&enodes[nodeno], &result); + assert(result.e_typ != EV_INT && result.e_typ != EV_ADDR); + if (result.e_typ == EV_REG) + { + int regno = result.e_v.e_reg; + erasereg(regno); + } + break; + } + case DO_TOKREPLACE: + { + register i; + int tinstno; + int repllen; + token_t reptoken[MAXREPLLEN]; - DEBUG("TOKREPLACE"); - assert(stackheight>=tokpatlen); - repllen=(codep[-1]>>5)&07; + DEBUG("TOKREPLACE"); + assert(stackheight >= tokpatlen); + repllen = (codep[-1] >> 5) & 07; #ifndef NDEBUG - if (Debug>2) - fprintf(stderr,"Stackheight=%d, tokpatlen=%d, repllen=%d %s\n", - stackheight,tokpatlen,repllen,inscoerc ? "(inscoerc)":""); + if (Debug > 2) + fprintf(stderr, "Stackheight=%d, tokpatlen=%d, repllen=%d %s\n", + stackheight, tokpatlen, repllen, inscoerc ? "(inscoerc)" : ""); #endif - for(i=0;i>5)&07; - j=emp-emlines; - if (emrepllen>j) { - assert(nemlines+emrepllen-j=0;i--) - emlines[i+emrepllen-j] = emlines[i]; - nemlines += emrepllen-j; - emp += emrepllen-j; - } - emp -= emrepllen; - for (i=0;i> 5) & 07; + j = emp - emlines; + if (emrepllen > j) + { + assert(nemlines + emrepllen - j < MAXEMLINES); + for (i = nemlines; i >= 0; i--) + emlines[i + emrepllen - j] = emlines[i]; + nemlines += emrepllen - j; + emp += emrepllen - j; + } + emp -= emrepllen; + for (i = 0; i < emrepllen; i++) + { + getint(eminstr, codep); + getint(nodeno, codep); + emp[i].em_instr = eminstr; + compute(&enodes[nodeno], &result[i]); + } + for (i = 0; i < emrepllen; i++) + { + switch (result[i].e_typ) + { + default: + assert(FALSE); + case 0: + emp[i].em_optyp = OPNO; + emp[i].em_soper = 0; + break; + case EV_INT: + emp[i].em_optyp = OPINT; + emp[i].em_soper = tostring(result[i].e_v.e_con); + emp[i].em_u.em_ioper = result[i].e_v.e_con; + break; + case EV_ADDR: + emp[i].em_optyp = OPSYMBOL; + emp[i].em_soper = ad2str(result[i].e_v.e_addr); + break; + } + } + if (!toplevel) + { + ply += emrepllen; #ifndef NDEBUG - if (Debug > 4) - fprintf(stderr, "ply becomes %d\n", ply); + if (Debug > 4) + fprintf(stderr, "ply becomes %d\n", ply); #endif - } - break; - } - case DO_COST: { - cost_t cost; + } + break; + } + case DO_COST: + { + cost_t cost; - DEBUG("COST"); - getint(cost.ct_space,codep); - getint(cost.ct_time,codep); - totalcost += costcalc(cost); - CHKCOST(); - break; - } + DEBUG("COST"); + getint(cost.ct_space, codep); + getint(cost.ct_time, codep); + totalcost += costcalc(cost); + CHKCOST(); + break; + } #ifdef REGVARS - case DO_PRETURN: { - if (toplevel) { - swtxt(); - regreturn(); /* in mach.c */ - } - break; - } + case DO_PRETURN: + { + if (toplevel) + { + swtxt(); + regreturn(); /* in mach.c */ + } + break; + } #endif - case DO_RETURN: - DEBUG("RETURN"); - assert(origcp!=startupcode); + case DO_RETURN: + DEBUG("RETURN"); + assert(origcp != startupcode); #ifndef NDEBUG - level--; + level--; #endif - return(totalcost); + return (totalcost); #ifdef USE_TES - case DO_LABDEF: { - int index; + case DO_LABDEF: + { + int index; - DEBUG("LABDEF"); - getint(index,codep); - if (toplevel) { - swtxt(); - printlabel(index); - } + DEBUG("LABDEF"); + getint(index, codep); + if (toplevel) + { + swtxt(); + printlabel(index); + } - break; - } + break; + } #endif + } } - } - doreturn: +doreturn: #ifdef ALLOW_NEXTEM - if (toplevel && totalcost == INFINITY && ! paniced) { + if (toplevel && totalcost == INFINITY && !paniced) + { DEBUG("PANIC!"); - totalcost += stackupto(&fakestack[stackheight-1], ply, toplevel); + totalcost += stackupto(&fakestack[stackheight - 1], ply, toplevel); #ifndef NDEBUG if (Debug > 2) fprintf(stderr, "Stackheight = %d\n", stackheight); @@ -929,18 +1092,21 @@ normalfailed: if (stackpad!=tokpatlen) { #ifndef NDEBUG level--; #endif - return(totalcost); + return (totalcost); } -readcodebytes() { +readcodebytes() +{ #ifndef CODEINC register fd; extern int ncodebytes; - if ((fd=open("code",0))<0) { + if ((fd = open("code", 0)) < 0) + { error("Can't open code"); } - if (read(fd,coderules,ncodebytes)!=ncodebytes) { + if (read(fd, coderules, ncodebytes) != ncodebytes) + { error("Short read from code"); } close(fd); @@ -948,30 +1114,34 @@ readcodebytes() { } #ifdef TABLEDEBUG -initlset(f) char *f; { - extern char *myalloc(); +initlset(f) char* f; +{ + extern char* myalloc(); set_flag = f; - if ((set_fd=open(f+1,2))<0) - error("Can't open %s rw",f+1); - read(set_fd,&set_size,sizeof(int)); - set_val=( short *) myalloc(set_size); - read(set_fd,set_val,set_size); + if ((set_fd = open(f + 1, 2)) < 0) + error("Can't open %s rw", f + 1); + read(set_fd, &set_size, sizeof(int)); + set_val = (short*)myalloc(set_size); + read(set_fd, set_val, set_size); } -termlset() { +termlset() +{ - if (set_fd) { - lseek(set_fd,(long) sizeof(int),0); - write(set_fd,set_val,set_size); + if (set_fd) + { + lseek(set_fd, (long)sizeof(int), 0); + write(set_fd, set_val, set_size); close(set_fd); - if (set_flag[0]=='u') { + if (set_flag[0] == 'u') + { register i; - - fprintf(stderr,"Unused code rules:\n\n"); - for(i=0;i<8*set_size;i++) - if(set_val[i>>4]&(1<<(i&017))) - fprintf(stderr,"\"%s\", line %d\n",tablename,i); + + fprintf(stderr, "Unused code rules:\n\n"); + for (i = 0; i < 8 * set_size; i++) + if (set_val[i >> 4] & (1 << (i & 017))) + fprintf(stderr, "\"%s\", line %d\n", tablename, i); } } } From 2cdcc16bc236e7277342077c1f6aab2fc3e93cda Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 16 Jan 2017 22:44:37 +0100 Subject: [PATCH 08/10] Fix a buffer overrun that was manifesting on OpenBSD; also fix a bounds check and some uninitialised variable problems. --- mach/proto/ncg/codegen.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mach/proto/ncg/codegen.c b/mach/proto/ncg/codegen.c index 8c7958cf2..95a3c012d 100644 --- a/mach/proto/ncg/codegen.c +++ b/mach/proto/ncg/codegen.c @@ -66,8 +66,7 @@ short* set_val; char* set_flag; #endif -unsigned codegen(codep, ply, toplevel, costlimit, forced) byte* codep; -unsigned costlimit; +unsigned codegen(byte* codep, int ply, int toplevel, unsigned costlimit, int forced) { #ifndef NDEBUG byte* origcp = codep; @@ -75,7 +74,7 @@ unsigned costlimit; #endif unsigned totalcost = 0; int inscoerc = 0; - int procarg[MAXPROCARG + 1]; + int procarg[MAXPROCARG + 1] = {}; #ifdef ALLOW_NEXTEM static int paniced; char* savebp = 0; @@ -328,7 +327,6 @@ unsigned costlimit; tokpatlen = (codep[-1] >> 5) & 07; for (i = 0; i < tokpatlen; i++) getint(tokexp[i], codep); - tokexp[i] = 0; tp = &fakestack[stackheight - 1]; i = 0; while (i < tokpatlen && tp >= fakestack) @@ -860,7 +858,7 @@ unsigned costlimit; swtxt(); if (stringno > 10000) { - assert(stringno < 100001 + MAXPROCARG); + assert(stringno < 10001 + MAXPROCARG); genstr(procarg[stringno - 10001]); } else From c471f617b7d8ddc48bc6faad1425678ec6353ee1 Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 16 Jan 2017 22:45:03 +0100 Subject: [PATCH 09/10] Ensure that memory is zero-initialised. --- mach/proto/ncg/salloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mach/proto/ncg/salloc.c b/mach/proto/ncg/salloc.c index e110d75ad..7ce1287bb 100644 --- a/mach/proto/ncg/salloc.c +++ b/mach/proto/ncg/salloc.c @@ -37,7 +37,7 @@ void chkstr(); string myalloc(size) { register string p; - p = (string) malloc((unsigned)size); + p = (string) calloc((unsigned)size, 1); if (p==0) fatal("Out of memory"); return(p); From 81c677d218a3f14c8b94e9dbfca055ba27f6610a Mon Sep 17 00:00:00 2001 From: David Given Date: Tue, 17 Jan 2017 22:31:38 +0100 Subject: [PATCH 10/10] Add a bunch more set operations to the PowerPC backends, and the Pascal test for the same. --- mach/powerpc/libem/and.s | 6 ++++-- mach/powerpc/libem/com.s | 6 ++++-- mach/powerpc/libem/ior.s | 2 +- mach/powerpc/libem/rck.s | 4 ++-- mach/powerpc/libem/set.s | 2 +- mach/powerpc/ncg/table | 30 ++++++++++++++++++++---------- mach/proto/mcg/treebuilder.c | 22 +++++++++++++++++----- plat/linuxppc/libsys/trap.s | 2 ++ plat/qemuppc/libsys/trap.s | 7 ------- tests/plat/pascalsets_p.p | 9 +++++++++ 10 files changed, 60 insertions(+), 30 deletions(-) diff --git a/mach/powerpc/libem/and.s b/mach/powerpc/libem/and.s index 4a1a81c04..727d79ec0 100644 --- a/mach/powerpc/libem/and.s +++ b/mach/powerpc/libem/and.s @@ -3,11 +3,13 @@ .sect .text ! Set intersection. -! Stack: ( b a -- a*b ) -! With r3 = size of set +! Stack: ( b a size -- a*b ) .define .and .and: + lwz r3, 0 (sp) ! r3 = size + addi sp, sp, 4 + mr r4, sp ! r4 = ptr to set a add r5, sp, r3 ! r5 = ptr to set b rlwinm r6, r3, 30, 2, 31 diff --git a/mach/powerpc/libem/com.s b/mach/powerpc/libem/com.s index 8b7082332..084eeeb62 100644 --- a/mach/powerpc/libem/com.s +++ b/mach/powerpc/libem/com.s @@ -3,11 +3,13 @@ .sect .text ! Set complement. -! Stack: ( a -- ~a ) -! With r3 = size of set +! Stack: ( a size -- ~a ) .define .com .com: + lwz r3, 0 (sp) ! size + addi sp, sp, 4 + mr r4, sp ! r4 = pointer to set a rlwinm r5, r3, 30, 2, 31 mtspr ctr, r5 ! ctr = r3 / 4 diff --git a/mach/powerpc/libem/ior.s b/mach/powerpc/libem/ior.s index b3ebf81e9..363799e1d 100644 --- a/mach/powerpc/libem/ior.s +++ b/mach/powerpc/libem/ior.s @@ -3,7 +3,7 @@ .sect .text ! Set union. -! Stack: ( size b a -- a+b ) +! Stack: ( b a size -- a+b ) .define .ior .ior: diff --git a/mach/powerpc/libem/rck.s b/mach/powerpc/libem/rck.s index b716e5091..0d5717f16 100644 --- a/mach/powerpc/libem/rck.s +++ b/mach/powerpc/libem/rck.s @@ -3,13 +3,13 @@ .sect .text ! Bounds check. Traps if the value is out of range. -! Stack: ( descriptor value -- ) +! Stack: ( value descriptor -- value ) .define .rck .rck: lwz r3, 0 (sp) lwz r4, 4 (sp) - addi sp, sp, 8 + addi sp, sp, 4 ! leave value on stack lwz r5, 0 (r3) cmp cr0, 0, r4, r5 diff --git a/mach/powerpc/libem/set.s b/mach/powerpc/libem/set.s index daffb9c3d..b42881cd7 100644 --- a/mach/powerpc/libem/set.s +++ b/mach/powerpc/libem/set.s @@ -3,7 +3,7 @@ .sect .text ! Create singleton set. -! Stack: ( size bitnumber -- set ) +! Stack: ( bitnumber size -- set ) .define .set .set: diff --git a/mach/powerpc/ncg/table b/mach/powerpc/ncg/table index 6498c591c..6297f8889 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -1466,11 +1466,13 @@ PATTERNS yields %a pat and defined($1) /* AND set */ - with STACK - kills ALL - gen - move {CONST, $1}, R3 - bl {LABEL, ".and"} + leaving + loc $1 + cal ".and" + + pat and !defined($1) + leaving + cal ".and" pat ior $1==4 /* OR word */ with REG NOT_R @@ -1559,10 +1561,13 @@ PATTERNS yields {NOT_R, %1} pat com defined($1) /* NOT set */ - with STACK - gen - move {CONST, $1}, R3 - bl {LABEL, ".com"} + leaving + loc $1 + cal ".com" + + pat com !defined($1) + leaving + cal ".com" pat zer $1==4 /* Push zero */ leaving @@ -1663,6 +1668,10 @@ PATTERNS loc $1 cal ".inn" + pat inn !defined($1) + leaving + cal ".inn" + /* Boolean resolutions */ @@ -2053,13 +2062,14 @@ PATTERNS ass 4 pat lae rck $2==4 /* Range check */ - with GPR + with REG uses CR0 gen cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 1)} bc IFTRUE, LT, {LABEL, ".trap_erange"} cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 2)} bc IFTRUE, GT, {LABEL, ".trap_erange"} + yields %1 diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index ba4f7198f..eed770170 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -519,7 +519,19 @@ static void insn_simple(int opcode) } case op_trp: helper_function(".trp"); break; - case op_sig: helper_function(".sig"); break; + + case op_sig: + { + struct ir* value = pop(EM_pointersize); + appendir( + store( + EM_pointersize, + new_labelir(".trppc"), 0, + value + ) + ); + break; + } case op_rtt: { @@ -614,7 +626,7 @@ static void simple_alu1(int opcode, int size, int irop, const char* fallback) if (size > (2*EM_wordsize)) { if (!fallback) - fatal("treebuilder: can't do opcode %d with size %d", opcode, size); + fatal("treebuilder: can't do opcode %s with size %d", em_mnem[opcode - sp_fmnem], size); push( new_wordir(size) ); @@ -638,7 +650,7 @@ static void simple_alu2(int opcode, int size, int irop, const char* fallback) if (size > (2*EM_wordsize)) { if (!fallback) - fatal("treebuilder: can't do opcode %d with size %d", opcode, size); + fatal("treebuilder: can't do opcode %s with size %d", em_mnem[opcode - sp_fmnem], size); push( new_wordir(size) ); @@ -751,10 +763,10 @@ static void insn_ivalue(int opcode, arith value) case op_rmu: simple_alu2(opcode, value, IR_MODU, NULL); break; case op_dvu: simple_alu2(opcode, value, IR_DIVU, NULL); break; - case op_and: simple_alu2(opcode, value, IR_AND, NULL); break; + case op_and: simple_alu2(opcode, value, IR_AND, ".and"); break; case op_ior: simple_alu2(opcode, value, IR_OR, ".ior"); break; case op_xor: simple_alu2(opcode, value, IR_EOR, NULL); break; - case op_com: simple_alu1(opcode, value, IR_NOT, NULL); break; + case op_com: simple_alu1(opcode, value, IR_NOT, ".com"); break; case op_adf: simple_alu2(opcode, value, IR_ADDF, NULL); break; case op_sbf: simple_alu2(opcode, value, IR_SUBF, NULL); break; diff --git a/plat/linuxppc/libsys/trap.s b/plat/linuxppc/libsys/trap.s index 296f17391..93c5189a4 100644 --- a/plat/linuxppc/libsys/trap.s +++ b/plat/linuxppc/libsys/trap.s @@ -63,7 +63,9 @@ EUNIMPL = 63 ! unimplemented em-instruction called addi r3, r0, ERANGE b .trap +.define .trp .define .trap +.trp: .trap: cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored bc IFTRUE, LT, 1f diff --git a/plat/qemuppc/libsys/trap.s b/plat/qemuppc/libsys/trap.s index 280adc33b..e00c4d561 100644 --- a/plat/qemuppc/libsys/trap.s +++ b/plat/qemuppc/libsys/trap.s @@ -63,10 +63,3 @@ EUNIMPL = 63 ! unimplemented em-instruction called .trp: .trap: b .trp ! spin forever - -.define .sig -.sig: - lwz r3, 0(sp) - li32 r4, .trppc - stw r3, 0(r4) - bclr ALWAYS, 0, 0 ! return diff --git a/tests/plat/pascalsets_p.p b/tests/plat/pascalsets_p.p index 3253414f9..b443b492d 100644 --- a/tests/plat/pascalsets_p.p +++ b/tests/plat/pascalsets_p.p @@ -24,5 +24,14 @@ begin for i := 0 to 255 do s := s + [chr(i)]; + i := 99; (* to defeat optimisation *) + ASSERT(chr(42) in s); + ASSERT(chr(142) in s); + ASSERT(chr(i) in s); + s := s - [chr(42)]; + ASSERT(not(chr(42) in s)); + ASSERT(chr(142) in s); + ASSERT(chr(i) in s); + finished end.