Add long long comparisons, shifts for linux386.

Add tests for comparisons and shifts.  Also add enough integer
conversions to compile the shift test (llshift_e.c), and disable
some wrong rules for ldc and conversions.
This commit is contained in:
George Koehler 2019-09-07 16:20:33 -04:00
parent 20a4d401d0
commit fb9f5387b5
4 changed files with 361 additions and 1 deletions

View file

@ -234,8 +234,12 @@ jmp label cost(1,4).
proccall "call" label+rm cost(1,8).
jxx "syntax error" label cost(1,4).
setxx "syntax error" REG1:rw cost(2,4).
seta REG1:rw cost(2,4).
setb REG1:rw cost(2,4).
setl REG1:rw cost(2,4).
setle REG1:rw cost(2,4).
setg REG1:rw cost(2,4).
setne REG1:rw cost(2,4).
lea anyreg:rw, halfindir:ro.
lea LOCAL:rw, halfindir:ro. /* only for register variables, UNSAFE!!! */
leave cost(1,4).
@ -255,12 +259,14 @@ movzxb anyreg:wo, REG+rm1:ro.
movzx anyreg:wo, REG+rm2:ro.
mul rmorconst:ro kills :cc eax edx cost(2,41).
neg rmorconst:rw:cc.
negb rm1:rw:cc.
not rmorconst:rw.
#ifdef REGVARS
or LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
#endif
or rm:rw:cc, regorconst:ro.
or anyreg:rw:cc, rmorconst:ro.
orb REG1:rw, REG1:ro.
pop anyreg:wo cost(1,4).
pop rm:wo.
push anyreg:ro cost(1,2).
@ -276,7 +282,9 @@ sar rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
sbb rm:rw:cc, regorconst:ro.
sbb anyreg:rw:cc, rmorconst:ro.
shl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
shld rm:rw, anyreg:ro, ANYCON+SHIFT_CREG:ro kills :cc cost(2,3).
shr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
shrd rm:rw, anyreg:ro, ANYCON+SHIFT_CREG:ro kills :cc cost(2,3).
#ifdef REGVARS
sub LOCAL:rw:cc, rmorconst:ro. /* only for register variables; UNSAFE !!! */
#endif
@ -506,7 +514,10 @@ PATTERNS
pat loc yields {ANYCON,$1}
#if 0
/* wrong because .Xtrp assumes trap < 16 */
pat ldc leaving loc 18 trp
#endif
pat lol yields {LOCAL,$1,4}
@ -1076,6 +1087,27 @@ with ANYCON REG
with SHIFT_CREG REG
gen sal %2,cl yields %2
pat sli $1==8
with SHIFT_CREG REG REG
gen testb cl,{ANYCON,32}
jne {label,1f}
shld %3,%2,cl
sal %2,cl
jmp {label,2f}
1:
mov %3,%2
sal %3,cl
xor %2,%2
2: yields %3 %2
pat loc sli ($1&32)==0 && $2==8
with REG REG
gen shld %2,%1,{ANYCON,$1&31}
sal %1,{ANYCON,$1&31} yields %2 %1
pat loc sli ($1&32)!=0 && $2==8
with REG REG
gen sal %1,{ANYCON,$1&31} yields %1 {ANYCON,0}
/*
pat sli !defined($1)
with ACC
@ -1089,6 +1121,29 @@ with SHIFT_CREG REG
with ANYCON REG
gen sar %2,%1 yields %2
pat sri $1==8
with SHIFT_CREG REG REG
gen testb cl,{ANYCON,32}
jne {label,1f}
shrd %2,%3,cl
sar %3,cl
jmp {label,2f}
1:
mov %2,%3
sar %2,cl
sar %3,{ANYCON,31}
2: yields %3 %2
pat loc sri ($1&32)==0 && $2==8
with REG REG
gen shrd %1,%2,{ANYCON,$1&31}
sar %2,{ANYCON,$1&31} yields %2 %1
pat loc sri ($1&32)!=0 && $2==8
with REG REG
gen mov %1,%2
sar %1,{ANYCON,$1&31}
sar %2,{ANYCON,31} yields %2 %1
/*
pat sri !defined($1)
with ACC
@ -1181,6 +1236,27 @@ gen shr %2,cl yields %2
with ANYCON REG
gen shr %2,%1 yields %2
pat sru $1==8
with SHIFT_CREG REG REG
gen testb cl,{ANYCON,32}
jne {label,1f}
shrd %2,%3,cl
shr %3,cl
jmp {label,2f}
1:
mov %2,%3
shr %2,cl
xor %3,%3
2: yields %3 %2
pat loc sru ($1&32)==0 && $2==8
with REG REG
gen shrd %2,%1,{ANYCON,$1&31}
shr %1,{ANYCON,$1&31} yields %2 %1
pat loc sru ($1&32)!=0 && $2==8
with REG REG
gen shr %2,{ANYCON,$1&31} yields {ANYCON,0} %2
/*
pat sru !defined($1)
with ACC STACK
@ -2085,10 +2161,13 @@ with CXREG DXREG ACC
kills ALL
gen proccall {label,".cii"} yields %3
#if 0
/* wrong when integer size > 4 */
pat ciu leaving cuu
pat cui leaving cuu
pat cuu
#endif
pat loc loc cii zeq $1==1
with GENREG STACK
@ -2123,10 +2202,25 @@ with exact rm2
uses reusing %1,GENREG
gen movsx %a,%1 yields %a
pat loc loc cii $1==4 && $2==8
with ACC
gen cdq. yields edx eax
pat loc loc cii $1<4 && $2==8 leaving loc $1 loc 4 cii loc 4 loc $2 cii
pat loc loc cii $1==8 && $2<=4
with a_word a_word yields %1
pat loc loc ciu leaving loc $1 loc $2 cuu
pat loc loc cui leaving loc $1 loc $2 cuu
pat loc loc cuu $1==$2
pat loc loc cuu $1==$2 || ($1<=4 && $2<=4)
pat loc loc cuu $1<=4 && $2==8
with a_word yields {ANYCON,0} %1
pat loc loc cuu $1==8 && $2<=4
with a_word a_word yields %1
pat loc loc cif $1==4 && $2==4 leaving loc 4 cal ".cif4" asp 4
pat loc loc cif $1==4 && $2==8 leaving loc 4 cal ".cif8"
@ -2432,8 +2526,31 @@ with rmorconst register
dec %a
2: yields %a
pat cmi $1==8
with rmorconst rmorconst GENREG GENREG
/* Let dx = 0x100 or 0x101 if a < b, 0 if a == b, 1 if a > b.
Shift left so 0x100 becomes the sign bit of edx. */
/* can't use 5th REG */
gen sub %3,%1
setne %3.1
sbb %4,%2
setl %4.2
setg %4.1
orb %4.1,%3.1
shl %4,{ANYCON,23} yields %4
pat cmu $1==4 leaving cmp
pat cmu $1==8
with rmorconst rmorconst GENREG GENREG
gen sub %3,%1
setne %3.1
sbb %4,%2
setb %4.2
seta %4.1
orb %4.1,%3.1
shl %4,{ANYCON,23} yields %4
pat cms $1==4
with REG rmorconst
gen sub %1,%2 yields %1
@ -2594,6 +2711,49 @@ pat cmp zgt call cmxzxx("ja","jb")
pat cms zeq $1==4 call cmxzxx("je","je")
pat cms zne $1==4 call cmxzxx("jne","jne")
proc cmx8txxn example cmi tgt
with GENREG REG rmorconst rmorconst
/* can't use 5th REG */
gen sub %1,%3
sbb %2,%4
setxx* %2.1
movzxb %2,%2.1 yields %2
proc cmx8txxy example cmi tlt
with rmorconst rmorconst GENREG REG
gen sub %3,%1
sbb %4,%2
setxx* %4.1
movzxb %4,%4.1 yields %4
pat cmi tlt $1==8 call cmx8txxy("setl")
pat cmi tle $1==8 call cmx8txxn("setge")
pat cmi tge $1==8 call cmx8txxy("setge")
pat cmi tgt $1==8 call cmx8txxn("setl")
pat cmu tlt $1==8 call cmx8txxy("setb")
pat cmu tle $1==8 call cmx8txxn("setae")
pat cmu tge $1==8 call cmx8txxy("setae")
pat cmu tgt $1==8 call cmx8txxn("setb")
proc cmx8zxxn example cmi zgt
with REG REG rmorconst rmorconst STACK
gen sub %1,%3
sbb %2,%4
jxx* {label,$2}
proc cmx8zxxy example cmi zlt
with rmorconst rmorconst REG REG STACK
gen sub %3,%1
sbb %4,%2
jxx* {label,$2}
pat cmi zlt $1==8 call cmx8zxxy("jl")
pat cmi zle $1==8 call cmx8zxxn("jge")
pat cmi zge $1==8 call cmx8zxxy("jge")
pat cmi zgt $1==8 call cmx8zxxn("jl")
pat cmu zlt $1==8 call cmx8zxxy("jb")
pat cmu zle $1==8 call cmx8zxxn("jae")
pat cmu zge $1==8 call cmx8zxxy("jae")
pat cmu zgt $1==8 call cmx8zxxn("jb")
pat cms zne $1==8
with regorconst regorconst rm rm STACK
gen cmp %3,%1

View file

@ -4,6 +4,7 @@ definerule("plat_testsuite",
{
plat = { type="string" },
method = { type="string" },
-- added long-long/llshift_e.c
sets = { type="table", default={"core", "b", "bugs", "m2", "floats", "long-long"}},
skipsets = { type="table", default={}},
tests = { type="targets", default={} },

View file

@ -0,0 +1,124 @@
#include "test.h"
struct s_cmp {
long long a;
long long b;
int a_cmp_b; /* -1 if a < b, 0 if a == b, 1 if a > b */
} s_cases[] = {
{-1LL, -1LL, 0},
{-1LL, 0LL, -1},
{-1LL, 1LL, -1},
{ 0LL, -1LL, 1},
{ 0LL, 0LL, 0},
{ 0LL, 1LL, -1},
{ 1LL, -1LL, 1},
{ 1LL, 0LL, 1},
{ 1LL, 1LL, 0},
};
struct u_cmp {
unsigned long long a;
unsigned long long b;
int a_cmp_b;
} u_cases[] = {
{ 0ULL, 0ULL, 0},
{ 0ULL, 1ULL, -1},
{ 1ULL, 0ULL, 1},
{ 1ULL, 1ULL, 0},
};
#define LEN(ary) (sizeof(ary) / sizeof(ary[0]))
/* Compiler should not optimize !t[a < b] as a > b. */
int t[] = {0, 1};
void _m_a_i_n(void) {
int i;
#define A c->a
#define B c->b
for (i = 0; i < LEN(s_cases); i++) {
struct s_cmp *c = &s_cases[i];
switch (c->a_cmp_b) {
case -1:
ASSERT(A < B);
ASSERT(A <= B);
ASSERT(A != B);
ASSERT(t[A < B]);
ASSERT(t[A <= B]);
ASSERT(!t[A == B]);
ASSERT(t[A != B]);
ASSERT(!t[A >= B]);
ASSERT(!t[A > B]);
break;
case 0:
ASSERT(A <= B);
ASSERT(A == B);
ASSERT(A >= B);
ASSERT(!t[A < B]);
ASSERT(t[A <= B]);
ASSERT(t[A == B]);
ASSERT(!t[A != B]);
ASSERT(t[A >= B]);
ASSERT(!t[A > B]);
break;
case 1:
ASSERT(A != B);
ASSERT(A >= B);
ASSERT(A > B);
ASSERT(!t[A < B]);
ASSERT(!t[A <= B]);
ASSERT(!t[A == B]);
ASSERT(t[A != B]);
ASSERT(t[A >= B]);
ASSERT(t[A > B]);
break;
default:
ASSERT(0);
break;
}
}
for (i = 0; i < LEN(u_cases); i++) {
struct u_cmp *c = &u_cases[i];
switch (c->a_cmp_b) {
case -1:
ASSERT(A < B);
ASSERT(A <= B);
ASSERT(A != B);
ASSERT(t[A < B]);
ASSERT(t[A <= B]);
ASSERT(!t[A == B]);
ASSERT(t[A != B]);
ASSERT(!t[A >= B]);
ASSERT(!t[A > B]);
break;
case 0:
ASSERT(A <= B);
ASSERT(A == B);
ASSERT(A >= B);
ASSERT(!t[A < B]);
ASSERT(t[A <= B]);
ASSERT(t[A == B]);
ASSERT(!t[A != B]);
ASSERT(t[A >= B]);
ASSERT(!t[A > B]);
break;
case 1:
ASSERT(A != B);
ASSERT(A >= B);
ASSERT(A > B);
ASSERT(!t[A < B]);
ASSERT(!t[A <= B]);
ASSERT(!t[A == B]);
ASSERT(t[A != B]);
ASSERT(t[A >= B]);
ASSERT(t[A > B]);
break;
default:
ASSERT(0);
break;
}
}
finished();
}

View file

@ -0,0 +1,75 @@
#include "test.h"
/*
* i << 1 is a constant shift. i << (1 + zero) is a variable shift,
* and may use a different rule in some code generators.
*/
int zero = 0;
long long i = 121LL;
long long j = 224690292230LL;
unsigned long long u = 12022195707510591570ULL;
void _m_a_i_n(void) {
ASSERT(i << 0 == 121LL);
ASSERT(i << (0 + zero) == 121LL);
ASSERT(i << 1 == 242LL);
ASSERT(i << (1 + zero) == 242LL);
ASSERT(i << 26 == 8120172544LL);
ASSERT(i << (26 + zero) == 8120172544LL);
ASSERT(i << 56 == 8718968878589280256LL);
ASSERT(i << (56 + zero) == 8718968878589280256LL);
ASSERT(i >> 0 == 121LL);
ASSERT(i >> (0 + zero) == 121LL);
ASSERT(i >> 1 == 60LL);
ASSERT(i >> (1 + zero) == 60LL);
ASSERT(i >> 7 == 0LL);
ASSERT(i >> (7 + zero) == 0LL);
ASSERT(i >> 37 == 0LL);
ASSERT(i >> (37 + zero) == 0LL);
ASSERT(-i >> 0 == -121LL);
ASSERT(-i >> (0 + zero) == -121LL);
ASSERT(-i >> 1 == -61LL);
ASSERT(-i >> (1 + zero) == -61LL);
ASSERT(-i >> 7 == -1LL);
ASSERT(-i >> (7 + zero) == -1LL);
ASSERT(-i >> 37 == -1LL);
ASSERT(-i >> (37 + zero) == -1LL);
ASSERT(j << 0 == 224690292230LL);
ASSERT(j << (0 + zero) == 224690292230LL);
ASSERT(j << 10 == 230082859243520LL);
ASSERT(j << (10 + zero) == 230082859243520LL);
ASSERT(j << 25 == 7539355131691663360LL);
ASSERT(j << (25 + zero) == 7539355131691663360LL);
ASSERT(j >> 0 == 224690292230LL);
ASSERT(j >> (0 + zero) == 224690292230LL);
ASSERT(j >> 6 == 3510785816LL);
ASSERT(j >> (6 + zero) == 3510785816LL);
ASSERT(j >> 32 == 52LL);
ASSERT(j >> (32 + zero) == 52LL);
ASSERT(j >> 38 == 0LL);
ASSERT(j >> (38 + zero) == 0LL);
ASSERT(-j >> 0 == -224690292230LL);
ASSERT(-j >> (0 + zero) == -224690292230LL);
ASSERT(-j >> 6 == -3510785817LL);
ASSERT(-j >> (6 + zero) == -3510785817LL);
ASSERT(-j >> 32 == -53LL);
ASSERT(-j >> (32 + zero) == -53LL);
ASSERT(-j >> 38 == -1LL);
ASSERT(-j >> (38 + zero) == -1LL);
ASSERT(u >> 0 == 12022195707510591570ULL);
ASSERT(u >> (0 + zero) == 12022195707510591570ULL);
ASSERT(u >> 1 == 6011097853755295785ULL);
ASSERT(u >> (1 + zero) == 6011097853755295785ULL);
ASSERT(u >> 41 == 5467061ULL);
ASSERT(u >> (41 + zero) == 5467061ULL);
finished();
}