diff --git a/mach/i386/ncg/table b/mach/i386/ncg/table index 10fd02809..184662a15 100644 --- a/mach/i386/ncg/table +++ b/mach/i386/ncg/table @@ -2339,12 +2339,56 @@ with SHIFT_CREG REG with ANYCON REG gen rol %2,%1 yields %2 +pat rol $1==8 +with SHIFT_CREG REG REG + uses REG + gen testb cl,{ANYCON,32} + je {label,1f} + xchg %2,%3 + 1: + mov %a,%3 + shld %3,%2,cl + shld %2,%a,cl yields %3 %2 + +pat loc rol ($1&32)==0 && $2==8 +with REG REG + uses REG + gen mov %a,%2 + shld %2,%1,{ANYCON,$1&31} + shld %1,%a,{ANYCON,$1&31} yields %2 %1 +pat loc rol ($1&63)==32 && $2==8 + leaving exg 4 +pat loc rol ($1&32)!=0 && $2==8 + leaving loc (0-$1)&31 ror 8 + pat ror $1==4 with SHIFT_CREG REG gen ror %2,cl yields %2 with ANYCON REG gen ror %2,%1 yields %2 +pat ror $1==8 +with SHIFT_CREG REG REG + uses REG + gen testb cl,{ANYCON,32} + je {label,1f} + xchg %2,%3 + 1: + mov %a,%2 + shrd %2,%3,cl + shrd %3,%a,cl yields %3 %2 + +pat loc ror ($1&32)==0 && $2==8 +with REG REG + uses REG + gen mov %a,%1 + shrd %1,%2,{ANYCON,$1&31} + shrd %2,%a,{ANYCON,$1&31} yields %2 %1 +pat loc ror ($1&63)==32 && $2==8 + leaving exg 4 +pat loc ror ($1&32)!=0 && $2==8 + leaving loc (0-$1)&31 rol 8 + /******************************************************************* * Group 10 : Set Instructions * *******************************************************************/ diff --git a/tests/plat/core/rotate_e.e b/tests/plat/core/rotate_e.e index 4fddbfd9f..499d834ed 100644 --- a/tests/plat/core/rotate_e.e +++ b/tests/plat/core/rotate_e.e @@ -10,6 +10,7 @@ * 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 long long size is 8, then also try 8-byte rotations. * * You can cheat this test if _cmu_ always pushes zero. */ @@ -54,6 +55,35 @@ val4left7 val4right11 con 2298473143U4 +#if _EM_LLSIZE == 8 +#define LEN8 4 + exa table8 + exa left8 + exa right8 +table8 /* left, right */ + con 14079773792309488728U8 /* 0, 0 */ + con 9712803510909425841U8 /* 1, 63 */ + con 10409556348460427178U8 /* 32, 32 */ + con 7039886896154744364U8 /* 63, 1 */ +left8 + con 0I2, 1I2, 32I2, 63I2 +right8 + con 0I2, 63I2, 32I2, 1I2 + + exa val8 + exa val8left13 + exa val8right20 + exa val8right32 +val8 + con 15129222862059184558U8 +val8left13 + con 13366998808072149566U8 +val8right20 + con 1881076513336495948U8 +val8right32 + con 17636555387978501128U8 +#endif + exp $_m_a_i_n pro $_m_a_i_n, _EM_WSIZE #define i -_EM_WSIZE @@ -219,5 +249,121 @@ val4right11 asp 4 8 +#if _EM_LLSIZE == 8 + /* + * Loop for LEN8 items in table8. + */ + loc 0 + stl i +9 + lae table8 + loi 8 /* value to rotate */ + lae left8 + lol i + loc 1 + sli _EM_WSIZE + ads _EM_WSIZE + loi 2 /* left distance */ + loc 2 + loc _EM_WSIZE + cii + rol 8 /* rotate left */ + lae table8 + lol i + loc 3 + sli _EM_WSIZE + ads _EM_WSIZE + loi 8 /* expected result */ + cmu 8 + zeq *10 + loc __LINE__ + loc _EM_WSIZE + loc 4 + cuu + cal $fail + asp 4 +10 + lae table8 + loi 8 /* value to rotate */ + lae right8 + lol i + loc 1 + sli _EM_WSIZE + ads _EM_WSIZE + loi 2 /* right distance */ + loc 2 + loc _EM_WSIZE + cii + ror 8 /* rotate right */ + lae table8 + lol i + loc 3 + sli _EM_WSIZE + ads _EM_WSIZE + loi 8 /* expected result */ + cmu 8 + zeq *11 + loc __LINE__ + loc _EM_WSIZE + loc 4 + cuu + cal $fail + asp 4 +11 + inl i /* loop LEN8 times */ + lol i + loc LEN8 + blt *9 + + /* + * Rotate 8-byte value by constant distance. + */ + lae val8 + loi 8 + loc 13 + rol 8 /* rotate left by 13 bits */ + lae val8left13 + loi 8 + cmu 8 + zeq *12 + loc __LINE__ + loc _EM_WSIZE + loc 4 + cuu + cal $fail + asp 4 +12 + lae val8 + loi 8 + loc 20 + ror 8 /* rotate right by 20 bits */ + lae val8right20 + loi 8 + cmu 8 + zeq *13 + loc __LINE__ + loc _EM_WSIZE + loc 4 + cuu + cal $fail + asp 4 +13 + lae val8 + loi 8 + loc 32 + ror 8 /* rotate right by 32 bits */ + lae val8right32 + loi 8 + cmu 8 + zeq *14 + loc __LINE__ + loc _EM_WSIZE + loc 4 + cuu + cal $fail + asp 4 +14 +#endif /* _EM_LLSIZE == 8 */ + cal $finished end