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
! 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

View file

@ -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

View file

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

View file

@ -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

View file

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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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.