summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/rs6000.md76
1 files changed, 38 insertions, 38 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 22787e2f70e..001884cbe58 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2264,8 +2264,7 @@
(bswap:DI
(match_operand:DI 1 "reg_or_mem_operand" "")))
(clobber (match_scratch:DI 2 ""))
- (clobber (match_scratch:DI 3 ""))
- (clobber (match_scratch:DI 4 ""))])]
+ (clobber (match_scratch:DI 3 ""))])]
""
{
if (!REG_P (operands[0]) && !REG_P (operands[1]))
@@ -2283,11 +2282,10 @@
;; Power7/cell has ldbrx/stdbrx, so use it directly
(define_insn "*bswapdi2_ldbrx"
- [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
+ [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:DI 2 "=X,X,&r"))
- (clobber (match_scratch:DI 3 "=X,X,&r"))
- (clobber (match_scratch:DI 4 "=X,X,&r"))]
+ (clobber (match_scratch:DI 3 "=X,X,&r"))]
"TARGET_POWERPC64 && TARGET_LDBRX
&& (REG_P (operands[0]) || REG_P (operands[1]))"
"@
@@ -2299,11 +2297,10 @@
;; Non-power7/cell, fall back to use lwbrx/stwbrx
(define_insn "*bswapdi2_64bit"
- [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
+ [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:DI 2 "=&b,&b,&r"))
- (clobber (match_scratch:DI 3 "=&r,&r,&r"))
- (clobber (match_scratch:DI 4 "=&r,X,&r"))]
+ (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
"TARGET_POWERPC64 && !TARGET_LDBRX
&& (REG_P (operands[0]) || REG_P (operands[1]))
&& !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
@@ -2315,8 +2312,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
(clobber (match_operand:DI 2 "gpc_reg_operand" ""))
- (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
- (clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
+ (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
"TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
[(const_int 0)]
"
@@ -2325,15 +2321,14 @@
rtx src = operands[1];
rtx op2 = operands[2];
rtx op3 = operands[3];
- rtx op4 = operands[4];
rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
BYTES_BIG_ENDIAN ? 4 : 0);
- rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode,
- BYTES_BIG_ENDIAN ? 4 : 0);
+ rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
+ BYTES_BIG_ENDIAN ? 4 : 0);
rtx addr1;
rtx addr2;
- rtx word_high;
- rtx word_low;
+ rtx word1;
+ rtx word2;
addr1 = XEXP (src, 0);
if (GET_CODE (addr1) == PLUS)
@@ -2358,21 +2353,22 @@
addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
}
+ word1 = change_address (src, SImode, addr1);
+ word2 = change_address (src, SImode, addr2);
+
if (BYTES_BIG_ENDIAN)
{
- word_high = change_address (src, SImode, addr1);
- word_low = change_address (src, SImode, addr2);
+ emit_insn (gen_bswapsi2 (op3_32, word2));
+ emit_insn (gen_bswapsi2 (dest_32, word1));
}
else
{
- word_high = change_address (src, SImode, addr2);
- word_low = change_address (src, SImode, addr1);
+ emit_insn (gen_bswapsi2 (op3_32, word1));
+ emit_insn (gen_bswapsi2 (dest_32, word2));
}
- emit_insn (gen_bswapsi2 (op3_32, word_low));
- emit_insn (gen_bswapsi2 (op4_32, word_high));
- emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
- emit_insn (gen_iordi3 (dest, dest, op4));
+ emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
+ emit_insn (gen_iordi3 (dest, dest, op3));
DONE;
}")
@@ -2380,8 +2376,7 @@
[(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:DI 2 "gpc_reg_operand" ""))
- (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
- (clobber (match_operand:DI 4 "" ""))]
+ (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
"TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
[(const_int 0)]
"
@@ -2396,8 +2391,8 @@
BYTES_BIG_ENDIAN ? 4 : 0);
rtx addr1;
rtx addr2;
- rtx word_high;
- rtx word_low;
+ rtx word1;
+ rtx word2;
addr1 = XEXP (dest, 0);
if (GET_CODE (addr1) == PLUS)
@@ -2422,19 +2417,21 @@
addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
}
+ word1 = change_address (dest, SImode, addr1);
+ word2 = change_address (dest, SImode, addr2);
+
emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
+
if (BYTES_BIG_ENDIAN)
{
- word_high = change_address (dest, SImode, addr1);
- word_low = change_address (dest, SImode, addr2);
+ emit_insn (gen_bswapsi2 (word1, src_si));
+ emit_insn (gen_bswapsi2 (word2, op3_si));
}
else
{
- word_high = change_address (dest, SImode, addr2);
- word_low = change_address (dest, SImode, addr1);
+ emit_insn (gen_bswapsi2 (word2, src_si));
+ emit_insn (gen_bswapsi2 (word1, op3_si));
}
- emit_insn (gen_bswapsi2 (word_high, src_si));
- emit_insn (gen_bswapsi2 (word_low, op3_si));
DONE;
}")
@@ -2442,8 +2439,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:DI 2 "gpc_reg_operand" ""))
- (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
- (clobber (match_operand:DI 4 "" ""))]
+ (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
"TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
@@ -2467,7 +2463,7 @@
}")
(define_insn "bswapdi2_32bit"
- [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
+ [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
(bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
(clobber (match_scratch:SI 2 "=&b,&b,X"))]
"!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
@@ -2496,7 +2492,8 @@
if (GET_CODE (addr1) == PLUS)
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
- if (TARGET_AVOID_XFORM)
+ if (TARGET_AVOID_XFORM
+ || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
{
emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
addr2 = op2;
@@ -2504,7 +2501,8 @@
else
addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
}
- else if (TARGET_AVOID_XFORM)
+ else if (TARGET_AVOID_XFORM
+ || REGNO (addr1) == REGNO (dest2))
{
emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
addr2 = op2;
@@ -2519,6 +2517,8 @@
word2 = change_address (src, SImode, addr2);
emit_insn (gen_bswapsi2 (dest2, word1));
+ /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
+ thus allowing us to omit an early clobber on the output. */
emit_insn (gen_bswapsi2 (dest1, word2));
DONE;
}")