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:
parent
20a4d401d0
commit
fb9f5387b5
|
@ -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
|
||||
|
|
|
@ -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={} },
|
||||
|
|
124
tests/plat/long-long/llcmp_e.c
Normal file
124
tests/plat/long-long/llcmp_e.c
Normal 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();
|
||||
}
|
||||
|
75
tests/plat/long-long/llshift_e.c
Normal file
75
tests/plat/long-long/llshift_e.c
Normal 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();
|
||||
}
|
||||
|
Loading…
Reference in a new issue