Skip to content

Commit 1f0bfbb

Browse files
committed
[xstormy16] Add support for byte and word swapping instructions.
This patch adds support for xstormy16's swpb (swap bytes) and swpw (swap words) instructions. The most obvious application of these to implement the __builtin_bswap16 and __builtin_bswap32 intrinsics. Currently, __builtin_bswap16 is implemented as: foo: mov r7,r2 shl r7,gcc-mirror#8 shr r2,gcc-mirror#8 or r2,r7 ret but with this patch becomes: foo: swpb r2 ret Likewise, __builtin_bswap32 now becomes: foo: swpb r2 | swpb r3 | swpw r2,r3 ret Finally, the swpw instruction on its own can be used to exchange two word mode registers without a temporary, so a new pattern and peephole2 have been added to catch this. As described in the PR rtl-optimization/106518, register allocation can (in theory) be more efficient on targets that provide a swap/exchange instruction. The slightly unusual swap<mode> naming matches that used in i386.md. 2024-04-26 Roger Sayle <[email protected]> gcc/ChangeLog * config/stormy16/stormy16.md (bswaphi2): New define_insn. (bswapsi2): New define_insn. (swaphi): New define_insn to exchange two registers (swpw). (define_peephole2): Recognize exchange of registers as swaphi. gcc/testsuite/ChangeLog * gcc.target/xstormy16/bswap16.c: New test case. * gcc.target/xstormy16/bswap32.c: Likewise. * gcc.target/xstormy16/swpb.c: Likewise. * gcc.target/xstormy16/swpw-1.c: Likewise. * gcc.target/xstormy16/swpw-2.c: Likewise.
1 parent 1e832b4 commit 1f0bfbb

File tree

6 files changed

+85
-0
lines changed

6 files changed

+85
-0
lines changed

gcc/config/stormy16/stormy16.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,3 +1265,39 @@
12651265
"bp %1,#7,%l0"
12661266
[(set_attr "length" "4")
12671267
(set_attr "psw_operand" "nop")])
1268+
1269+
(define_insn "bswaphi2"
1270+
[(set (match_operand:HI 0 "register_operand" "=r")
1271+
(bswap:HI (match_operand:HI 1 "register_operand" "0")))]
1272+
""
1273+
"swpb %0")
1274+
1275+
(define_insn "bswapsi2"
1276+
[(set (match_operand:SI 0 "register_operand" "=r")
1277+
(bswap:SI (match_operand:SI 1 "register_operand" "0")))]
1278+
""
1279+
"swpb %0 | swpb %h0 | swpw %0,%h0"
1280+
[(set_attr "length" "6")])
1281+
1282+
(define_insn "swaphi"
1283+
[(set (match_operand:HI 0 "register_operand" "+r")
1284+
(match_operand:HI 1 "register_operand" "+r"))
1285+
(set (match_dup 1)
1286+
(match_dup 0))]
1287+
""
1288+
"swpw %0,%1")
1289+
1290+
(define_peephole2
1291+
[(set (match_operand:HI 0 "register_operand")
1292+
(match_operand:HI 1 "register_operand"))
1293+
(set (match_dup 1)
1294+
(match_operand:HI 2 "register_operand"))
1295+
(set (match_dup 2)
1296+
(match_dup 0))]
1297+
"REGNO (operands[0]) != REGNO (operands[1])
1298+
&& REGNO (operands[0]) != REGNO (operands[2])
1299+
&& REGNO (operands[1]) != REGNO (operands[2])
1300+
&& peep2_reg_dead_p (3, operands[0])"
1301+
[(parallel [(set (match_dup 2) (match_dup 1))
1302+
(set (match_dup 1) (match_dup 2))])])
1303+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2" } */
3+
4+
unsigned short foo(unsigned short x)
5+
{
6+
return __builtin_bswap16 (x);
7+
}
8+
9+
/* { dg-final { scan-assembler "swpb r2" } } */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2" } */
3+
4+
unsigned long foo(unsigned long x)
5+
{
6+
return __builtin_bswap32 (x);
7+
}
8+
9+
/* { dg-final { scan-assembler "swpb" } } */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2" } */
3+
4+
unsigned short foo(unsigned short x)
5+
{
6+
return (x>>8) | (x<<8);
7+
}
8+
9+
/* { dg-final { scan-assembler "swpb r2" } } */
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2" } */
3+
4+
void ext(int x, int y);
5+
6+
void foo(int x, int y) { ext(y,x); }
7+
8+
/* { dg-final { scan-assembler "swpw r3,r2" } } */
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O2" } */
3+
4+
void ext(int x, int y);
5+
6+
void foo(int x, int y)
7+
{
8+
int t1 = x ^ y;
9+
int t2 = t1 ^ x;
10+
int t3 = t1 ^ y;
11+
ext(t2,t3);
12+
}
13+
14+
/* { dg-final { scan-assembler "swpw r3,r2" } } */

0 commit comments

Comments
 (0)