Add a bunch more set operations to the PowerPC backends, and the Pascal test

for the same.
This commit is contained in:
David Given 2017-01-17 22:31:38 +01:00
parent c471f617b7
commit 81c677d218
10 changed files with 60 additions and 30 deletions

View file

@ -3,11 +3,13 @@
.sect .text .sect .text
! Set intersection. ! Set intersection.
! Stack: ( b a -- a*b ) ! Stack: ( b a size -- a*b )
! With r3 = size of set
.define .and .define .and
.and: .and:
lwz r3, 0 (sp) ! r3 = size
addi sp, sp, 4
mr r4, sp ! r4 = ptr to set a mr r4, sp ! r4 = ptr to set a
add r5, sp, r3 ! r5 = ptr to set b add r5, sp, r3 ! r5 = ptr to set b
rlwinm r6, r3, 30, 2, 31 rlwinm r6, r3, 30, 2, 31

View file

@ -3,11 +3,13 @@
.sect .text .sect .text
! Set complement. ! Set complement.
! Stack: ( a -- ~a ) ! Stack: ( a size -- ~a )
! With r3 = size of set
.define .com .define .com
.com: .com:
lwz r3, 0 (sp) ! size
addi sp, sp, 4
mr r4, sp ! r4 = pointer to set a mr r4, sp ! r4 = pointer to set a
rlwinm r5, r3, 30, 2, 31 rlwinm r5, r3, 30, 2, 31
mtspr ctr, r5 ! ctr = r3 / 4 mtspr ctr, r5 ! ctr = r3 / 4

View file

@ -3,7 +3,7 @@
.sect .text .sect .text
! Set union. ! Set union.
! Stack: ( size b a -- a+b ) ! Stack: ( b a size -- a+b )
.define .ior .define .ior
.ior: .ior:

View file

@ -3,13 +3,13 @@
.sect .text .sect .text
! Bounds check. Traps if the value is out of range. ! Bounds check. Traps if the value is out of range.
! Stack: ( descriptor value -- ) ! Stack: ( value descriptor -- value )
.define .rck .define .rck
.rck: .rck:
lwz r3, 0 (sp) lwz r3, 0 (sp)
lwz r4, 4 (sp) lwz r4, 4 (sp)
addi sp, sp, 8 addi sp, sp, 4 ! leave value on stack
lwz r5, 0 (r3) lwz r5, 0 (r3)
cmp cr0, 0, r4, r5 cmp cr0, 0, r4, r5

View file

@ -3,7 +3,7 @@
.sect .text .sect .text
! Create singleton set. ! Create singleton set.
! Stack: ( size bitnumber -- set ) ! Stack: ( bitnumber size -- set )
.define .set .define .set
.set: .set:

View file

@ -1466,11 +1466,13 @@ PATTERNS
yields %a yields %a
pat and defined($1) /* AND set */ pat and defined($1) /* AND set */
with STACK leaving
kills ALL loc $1
gen cal ".and"
move {CONST, $1}, R3
bl {LABEL, ".and"} pat and !defined($1)
leaving
cal ".and"
pat ior $1==4 /* OR word */ pat ior $1==4 /* OR word */
with REG NOT_R with REG NOT_R
@ -1559,10 +1561,13 @@ PATTERNS
yields {NOT_R, %1} yields {NOT_R, %1}
pat com defined($1) /* NOT set */ pat com defined($1) /* NOT set */
with STACK leaving
gen loc $1
move {CONST, $1}, R3 cal ".com"
bl {LABEL, ".com"}
pat com !defined($1)
leaving
cal ".com"
pat zer $1==4 /* Push zero */ pat zer $1==4 /* Push zero */
leaving leaving
@ -1663,6 +1668,10 @@ PATTERNS
loc $1 loc $1
cal ".inn" cal ".inn"
pat inn !defined($1)
leaving
cal ".inn"
/* Boolean resolutions */ /* Boolean resolutions */
@ -2053,13 +2062,14 @@ PATTERNS
ass 4 ass 4
pat lae rck $2==4 /* Range check */ pat lae rck $2==4 /* Range check */
with GPR with REG
uses CR0 uses CR0
gen gen
cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 1)} cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 1)}
bc IFTRUE, LT, {LABEL, ".trap_erange"} bc IFTRUE, LT, {LABEL, ".trap_erange"}
cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 2)} cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 2)}
bc IFTRUE, GT, {LABEL, ".trap_erange"} bc IFTRUE, GT, {LABEL, ".trap_erange"}
yields %1

View file

@ -519,7 +519,19 @@ static void insn_simple(int opcode)
} }
case op_trp: helper_function(".trp"); break; 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: 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 (size > (2*EM_wordsize))
{ {
if (!fallback) 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( push(
new_wordir(size) 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 (size > (2*EM_wordsize))
{ {
if (!fallback) 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( push(
new_wordir(size) 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_rmu: simple_alu2(opcode, value, IR_MODU, NULL); break;
case op_dvu: simple_alu2(opcode, value, IR_DIVU, 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_ior: simple_alu2(opcode, value, IR_OR, ".ior"); break;
case op_xor: simple_alu2(opcode, value, IR_EOR, NULL); 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_adf: simple_alu2(opcode, value, IR_ADDF, NULL); break;
case op_sbf: simple_alu2(opcode, value, IR_SUBF, NULL); break; case op_sbf: simple_alu2(opcode, value, IR_SUBF, NULL); break;

View file

@ -63,7 +63,9 @@ EUNIMPL = 63 ! unimplemented em-instruction called
addi r3, r0, ERANGE addi r3, r0, ERANGE
b .trap b .trap
.define .trp
.define .trap .define .trap
.trp:
.trap: .trap:
cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored
bc IFTRUE, LT, 1f bc IFTRUE, LT, 1f

View file

@ -63,10 +63,3 @@ EUNIMPL = 63 ! unimplemented em-instruction called
.trp: .trp:
.trap: .trap:
b .trp ! spin forever b .trp ! spin forever
.define .sig
.sig:
lwz r3, 0(sp)
li32 r4, .trppc
stw r3, 0(r4)
bclr ALWAYS, 0, 0 ! return

View file

@ -24,5 +24,14 @@ begin
for i := 0 to 255 do for i := 0 to 255 do
s := s + [chr(i)]; 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 finished
end. end.