Add test for EM rol, ror. Fix i80, i86, powerpc.

EM instructions _rol_ and _ror_ do rotate an integer left or right.
Our compilers and optimizers never emit _rol_ nor _ror_, but I might
want to use them in the future.

Add _rol_ and _ror_ to powerpc.  Fix `rol 4` and `ror 4` in both i80
and i86, where the rules for `rol 4` and `ror 4` seem to have never
been tested until now.
This commit is contained in:
George Koehler 2017-12-07 17:16:21 -05:00
parent c95bcac91d
commit a1d1f38691
6 changed files with 264 additions and 7 deletions

View file

@ -25,8 +25,8 @@
mov e,a
mov a,b
ral
1: mov a,l
1: ral
mov a,l
ral
mov l,a
mov a,h

View file

@ -25,8 +25,8 @@
mov e,a
mov a,l
rar
1: mov a,b
1: rar
mov a,b
rar
mov b,a
mov a,c

View file

@ -2292,7 +2292,7 @@ with CXREG REG REG
rcl %3,{ANYCON,1}
adc %2,{ANYCON,0}
loop {label, 2b}
1:
1: yields %3 %2
pat loc ror $1==1 && $2==2
with REG
@ -2311,7 +2311,7 @@ with CXREG REG REG
rcl %3,{ANYCON,1}
adc %2,{ANYCON,0}
loop {label, 2b}
1:
1: yields %3 %2
/*******************************************************************
* Group 10 : Set Instructions *

View file

@ -307,7 +307,11 @@ INSTRUCTIONS
rlwinm GPR:wo, GPR:ro, CONST:ro, CONST:ro, CONST:ro.
extlwi GPR:wo, GPR:ro, CONST:ro, CONST:ro.
extrwi GPR:wo, GPR:ro, CONST:ro, CONST:ro.
rotlwi GPR:wo, GPR:ro, CONST:ro.
rotrwi GPR:wo, GPR:ro, CONST:ro.
srwi GPR:wo, GPR:ro, CONST:ro.
rlwnm GPR:wo, GPR:ro, GPR:ro, CONST:ro, CONST:ro.
rotlw GPR:wo, GPR:ro, GPR:ro.
slw GPR:wo, GPR:ro, GPR:ro.
subf GPR:wo, GPR:ro, GPR:ro.
sraw GPR:wo, GPR:ro, GPR:ro cost(4, 2).
@ -1232,6 +1236,9 @@ PATTERNS
subf %a, %a, %2
yields %a
/* Bitwise logic */
pat and $1==4 /* AND word */
with REG NOT_R
uses reusing %1, REG
@ -1381,6 +1388,9 @@ PATTERNS
loc $1
cal ".zer"
/* Shifts and rotations */
pat sli $1==4 /* Shift left (second << top) */
with CONST_STACK REG
uses reusing %2, REG
@ -1417,6 +1427,33 @@ PATTERNS
srw %a, %2, %1
yields %a
pat rol $1==4 /* Rotate left word */
with CONST_STACK REG
uses reusing %2, REG
gen rotlwi %a, %2, {CONST, %1.val & 0x1F}
yields %a
with REG REG
uses reusing %2, REG
gen rotlw %a, %2, %1
yields %a
/*
* ror 4 -> ngi 4, rol 4
* because to rotate right by n bits is to rotate left by
* (32 - n), which is to rotate left by -n. PowerPC rotlw
* handles -n as (-n & 0x1F).
*/
pat ror $1==4 /* Rotate right word */
with CONST_STACK REG
uses reusing %2, REG
gen rotrwi %a, %2, {CONST, %1.val & 0x1F}
yields %a
with /* anything */
leaving
ngi 4
rol 4
/* Arrays */

View file

@ -10,7 +10,8 @@ definerule("plat_testsuite",
-- target names will resolve there.
local testfiles = filenamesof(
"tests/plat/*.c",
"tests/plat/*.e",
"tests/plat/inn_e.e",
"tests/plat/rotate_e.e",
"tests/plat/*.p",
"tests/plat/b/*.b",
"tests/plat/bugs/bug-22-inn_mod.mod",

219
tests/plat/rotate_e.e Normal file
View file

@ -0,0 +1,219 @@
#
mes 2, EM_WSIZE, EM_PSIZE
/*
* Test _rol_ (rotate left) and _ror_ (rotate right).
*
* By tradition, _rol_ and _ror_ can't rotate values shorter than the
* word size, or longer than 4 bytes.
* - If word size is 2, then try rotating 2-byte and 4-byte values.
* - If word size is 4, then try rotating 4-byte values.
*/
#if EM_WSIZE == 2
#define LEN2 4
exa table2
exa left2
exa right2
table2 /* left, right */
con 12715U2 /* 0, 0 */
con 25430U2 /* 1, 15 */
con 43825U2 /* 8, 8 */
con 39125U2 /* 15, 1 */
left2
con 0I2, 1I2, 8I2, 15I2
right2
con 0I2, 15I2, 8I2, 1I2
#endif
#define LEN4 4
exa table4
exa left4
exa right4
table4 /* left, right */
con 437223536U4 /* 0, 0 */
con 874447072U4 /* 1, 31 */
con 2154830351U4 /* 16, 16 */
con 218611768U4 /* 31, 1 */
left4
con 0I2, 1I2, 16I2, 31I2
right4
con 0I2, 31I2, 16I2, 1I2
exa val4
exa val4left7
exa val4right11
val4
con 4283808839U4
val4left7
con 2866684927U4
val4right11
con 2298473143U4
exp $_m_a_i_n
pro $_m_a_i_n, EM_WSIZE
#define i -EM_WSIZE
#if EM_WSIZE == 2
/*
* Loop for LEN2 items in table2.
*/
loc 0
stl i
1
lae table2
loi 2 /* value to rotate */
lae left2
lol i
loc 1
sli EM_WSIZE
ads EM_WSIZE
loi 2 /* left distance */
rol 2 /* rotate left */
lae table2
lol i
loc 1
sli EM_WSIZE
ads EM_WSIZE
loi 2 /* expected result */
cmu 2
zeq *2
loc __LINE__
loc EM_WSIZE
loc 4
cuu
cal $fail
asp 4
2
lae table2
loi 2 /* value to rotate */
lae right2
lol i
loc 1
sli EM_WSIZE
ads EM_WSIZE
loi 2 /* right distance */
ror 2 /* rotate right */
lae table2
lol i
loc 1
sli EM_WSIZE
ads EM_WSIZE
loi 2 /* expected result */
cmu 2
zeq *3
loc __LINE__
loc EM_WSIZE
loc 4
cuu
cal $fail
asp 4
3
inl i /* loop LEN2 times */
lol i
loc LEN2
blt *1
#endif /* EM_WSIZE == 2 */
/*
* Loop for LEN4 items in table4.
*/
loc 0
stl i
4
lae table4
loi 4 /* value to rotate */
lae left4
lol i
loc 1
sli EM_WSIZE
ads EM_WSIZE
loi 2 /* left distance */
loc 2
loc EM_WSIZE
cii
rol 4 /* rotate left */
lae table4
lol i
loc 2
sli EM_WSIZE
ads EM_WSIZE
loi 4 /* expected result */
cmu 4
zeq *5
loc __LINE__
loc EM_WSIZE
loc 4
cuu
cal $fail
asp 4
5
lae table4
loi 4 /* value to rotate */
lae right4
lol i
loc 1
sli EM_WSIZE
ads EM_WSIZE
loi 2 /* right distance */
loc 2
loc EM_WSIZE
cii
ror 4 /* rotate right */
lae table4
lol i
loc 2
sli EM_WSIZE
ads EM_WSIZE
loi 4 /* expected result */
cmu 4
zeq *6
loc __LINE__
loc EM_WSIZE
loc 4
cuu
cal $fail
asp 4
6
inl i /* loop LEN4 times */
lol i
loc LEN4
blt *4
/*
* Rotate 4-byte values by a constant distance, because this uses
* different rules in PowerPC ncg.
*/
lae val4
loi 4
loc 7
rol 4 /* rotate left by 7 bits */
lae val4left7
loi 4
cmu 4
zeq *7
loc __LINE__
loc EM_WSIZE
loc 4
cuu
cal $fail
asp 4
7
lae val4
loi 4
loc 11
ror 4 /* rotate right by 11 bits */
lae val4right11
loi 4
cmu 4
zeq *8
loc __LINE__
loc EM_WSIZE
loc 4
cuu
cal $fail
asp 4
8
cal $finished
end