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.