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 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 */ 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); 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 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 61e099934..363799e1d 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: ( b a size -- 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..0d5717f16 --- /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: ( value descriptor -- value ) + +.define .rck +.rck: + lwz r3, 0 (sp) + lwz r4, 4 (sp) + addi sp, sp, 4 ! leave value on stack + + 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..b42881cd7 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: ( bitnumber size -- 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 d3d2fcbf4..1fc1f5b19 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -1476,11 +1476,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 @@ -1513,18 +1515,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 @@ -1573,21 +1571,22 @@ 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 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 @@ -1665,27 +1664,23 @@ 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" + + pat inn !defined($1) + leaving + cal ".inn" /* Boolean resolutions */ @@ -2076,6 +2071,17 @@ PATTERNS loc $1 ass 4 + pat lae rck $2==4 /* Range check */ + 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 + + /* Floating point support */ diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 667562e8d..eed770170 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; @@ -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: { @@ -528,10 +540,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 +554,7 @@ static void insn_simple(int opcode) ) ); break; - + case op_lpb: push( new_ir1( @@ -607,29 +621,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 %s with size %d", em_mnem[opcode - sp_fmnem], 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 %s with size %d", em_mnem[opcode - sp_fmnem], 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 +746,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, ".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, ".com"); 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 +916,7 @@ static void insn_ivalue(int opcode, arith value) ) ); break; - + case op_loc: push( new_wordir(value) @@ -1041,7 +1083,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 +1095,7 @@ static void insn_ivalue(int opcode, arith value) push(delta); break; } - + case op_dup: { sequence_point(); @@ -1084,6 +1126,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 +1162,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 +1220,7 @@ static void insn_ivalue(int opcode, arith value) ); break; } - + case op_lfr: { push( @@ -1300,11 +1351,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 +1371,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 +1392,7 @@ static void insn_ivalue(int opcode, arith value) ) ); break; - + case 1: push( appendir( @@ -1492,18 +1543,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 +1616,7 @@ static void insn_lvalue(int opcode, const char* label, arith offset) ) ); break; - + case op_ine: sequence_point(); appendir( @@ -1666,7 +1705,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 +1738,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/mach/proto/ncg/codegen.c b/mach/proto/ncg/codegen.c index 15d99d393..95a3c012d 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,1046 @@ 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(byte* codep, int ply, int toplevel, unsigned costlimit, int forced) +{ #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); + 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 < 10001 + 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 +1090,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 +1112,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); } } } 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); diff --git a/plat/linuxppc/libsys/trap.s b/plat/linuxppc/libsys/trap.s index 09d3b0b21..93c5189a4 100644 --- a/plat/linuxppc/libsys/trap.s +++ b/plat/linuxppc/libsys/trap.s @@ -52,43 +52,50 @@ 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 .trp .define .trap +.trp: .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 +103,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..e00c4d561 100644 --- a/plat/qemuppc/libsys/trap.s +++ b/plat/qemuppc/libsys/trap.s @@ -49,21 +49,17 @@ 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: .trap: b .trp ! spin forever - -.define .sig -.sig: - lwz r3, 0(sp) - li32 r4, .trppc - stw r3, 0(r4) - bclr ALWAYS, 0, 0 ! return - \ No newline at end of file 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__) diff --git a/tests/plat/pascalsets_p.p b/tests/plat/pascalsets_p.p new file mode 100644 index 000000000..b443b492d --- /dev/null +++ b/tests/plat/pascalsets_p.p @@ -0,0 +1,37 @@ +# +(*$U+ -- enables underscores in identifiers *) + +program pascalsets; + +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)]; + + 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.