aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2009-09-14 16:59:12 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2009-09-14 16:59:12 +0000
commit5910fb59b9df9dbdde8a70a71609c4bc1467a29b (patch)
treead3c1fb09c7be8aee817570885e9f6f2a67e66cf /gcc
parent6c1c1dfa24f6239c3d70c901693de65b3390da65 (diff)
downloadgcc-5910fb59b9df9dbdde8a70a71609c4bc1467a29b.zip
gcc-5910fb59b9df9dbdde8a70a71609c4bc1467a29b.tar.gz
gcc-5910fb59b9df9dbdde8a70a71609c4bc1467a29b.tar.bz2
Fix PR 41210 & 41331 on powerpc
From-SVN: r151691
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/rs6000/rs6000.c48
-rw-r--r--gcc/config/rs6000/rs6000.md30
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bswap64-4.c9
5 files changed, 65 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bd3cc25..8971af8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+2009-09-14 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/41210
+ * config/rs6000/rs6000.c (rs6000_function_value): V2DF and V2DI
+ are returned in the same register (vs34 or v2) that Altivec vector
+ types are returned in.
+ (rs6000_libcall_value): Ditto.
+
+ PR target/41331
+ * config/rs6000/rs6000.c (rs6000_emit_move): Use gen_add3_insn
+ instead of explicit addsi3/adddi3 calls.
+ (rs6000_split_multireg_move): Ditto.
+ (rs6000_emit_allocate_stack): Ditto.
+ (rs6000_emit_prologue): Ditto.
+ (rs6000_output_mi_thunk): Ditto.
+
+ * config/rs6000/rs6000.md (bswapdi*): Don't assume the pointer
+ size is 64 bits if we can use 64-bit registers.
+
2009-09-14 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin/bfin.c (bfin_longcall_p): Don't use short calls for weak
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 40d8390..f796c08 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -6488,10 +6488,7 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
rtx other = XEXP (XEXP (operands[1], 0), 1);
sym = force_reg (mode, sym);
- if (mode == SImode)
- emit_insn (gen_addsi3 (operands[0], sym, other));
- else
- emit_insn (gen_adddi3 (operands[0], sym, other));
+ emit_insn (gen_add3_insn (operands[0], sym, other));
return;
}
@@ -16473,9 +16470,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
: GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (breg, breg, delta_rtx)
- : gen_adddi3 (breg, breg, delta_rtx));
+ emit_insn (gen_add3_insn (breg, breg, delta_rtx));
src = replace_equiv_address (src, breg);
}
else if (! rs6000_offsettable_memref_p (src))
@@ -16525,9 +16520,7 @@ rs6000_split_multireg_move (rtx dst, rtx src)
used_update = true;
}
else
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (breg, breg, delta_rtx)
- : gen_adddi3 (breg, breg, delta_rtx));
+ emit_insn (gen_add3_insn (breg, breg, delta_rtx));
dst = replace_equiv_address (dst, breg);
}
else
@@ -17728,14 +17721,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12, int copy_r11)
&& REGNO (stack_limit_rtx) > 1
&& REGNO (stack_limit_rtx) <= 31)
{
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (tmp_reg,
- stack_limit_rtx,
- GEN_INT (size))
- : gen_adddi3 (tmp_reg,
- stack_limit_rtx,
- GEN_INT (size)));
-
+ emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
const0_rtx));
}
@@ -18648,9 +18634,7 @@ rs6000_emit_prologue (void)
rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx
? sp_reg_rtx : r11);
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (r11, ptr_reg, offset)
- : gen_adddi3 (r11, ptr_reg, offset));
+ emit_insn (gen_add3_insn (r11, ptr_reg, offset));
}
par = rs6000_make_savres_rtx (info, frame_reg_rtx,
@@ -20090,12 +20074,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
/* Apply the constant offset, if required. */
if (delta)
- {
- rtx delta_rtx = GEN_INT (delta);
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (this_rtx, this_rtx, delta_rtx)
- : gen_adddi3 (this_rtx, this_rtx, delta_rtx));
- }
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
/* Apply the offset from the vtable, if required. */
if (vcall_offset)
@@ -20106,9 +20085,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
{
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
- : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
+ emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
}
else
@@ -20117,9 +20094,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
}
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (this_rtx, this_rtx, tmp)
- : gen_adddi3 (this_rtx, this_rtx, tmp));
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
}
/* Generate a tail call to the target function. */
@@ -25002,6 +24977,10 @@ rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
&& TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode))
regno = ALTIVEC_ARG_RETURN;
+ else if (TREE_CODE (valtype) == VECTOR_TYPE
+ && TARGET_VSX && TARGET_ALTIVEC_ABI
+ && VSX_VECTOR_MODE (mode))
+ regno = ALTIVEC_ARG_RETURN;
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
&& (mode == DFmode || mode == DCmode
|| mode == TFmode || mode == TCmode))
@@ -25043,6 +25022,9 @@ rs6000_libcall_value (enum machine_mode mode)
else if (ALTIVEC_VECTOR_MODE (mode)
&& TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
regno = ALTIVEC_ARG_RETURN;
+ else if (VSX_VECTOR_MODE (mode)
+ && TARGET_VSX && TARGET_ALTIVEC_ABI)
+ regno = ALTIVEC_ARG_RETURN;
else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
return rs6000_complex_function_value (mode);
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d7f30f8..8ea90d8 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2392,9 +2392,11 @@
if (!REG_P (operands[0]) && !REG_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
- if (TARGET_32BIT)
+ if (!TARGET_POWERPC64)
{
- /* 32-bit needs fewer scratch registers. */
+ /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
+ that uses 64-bit registers needs the same scratch registers as 64-bit
+ mode. */
emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
DONE;
}
@@ -2453,13 +2455,13 @@
addr1 = XEXP (src, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_adddi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
- addr2 = gen_rtx_PLUS (DImode, op2, XEXP (addr1, 1));
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+ addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
}
else
{
emit_move_insn (op2, GEN_INT (4));
- addr2 = gen_rtx_PLUS (DImode, op2, addr1);
+ addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
}
if (BYTES_BIG_ENDIAN)
@@ -2503,13 +2505,13 @@
addr1 = XEXP (dest, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_adddi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
- addr2 = gen_rtx_PLUS (DImode, op2, XEXP (addr1, 1));
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
+ addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
}
else
{
emit_move_insn (op2, GEN_INT (4));
- addr2 = gen_rtx_PLUS (DImode, op2, addr1);
+ addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
}
emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
@@ -2559,7 +2561,7 @@
[(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_32BIT && (REG_P (operands[0]) || REG_P (operands[1]))"
+ "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
"#"
[(set_attr "length" "16,12,36")])
@@ -2567,7 +2569,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
- "TARGET_32BIT && reload_completed"
+ "!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
@@ -2584,7 +2586,7 @@
addr1 = XEXP (src, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_addsi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
}
else
@@ -2612,7 +2614,7 @@
[(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
- "TARGET_32BIT && reload_completed"
+ "!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
@@ -2629,7 +2631,7 @@
addr1 = XEXP (dest, 0);
if (GET_CODE (addr1) == PLUS)
{
- emit_insn (gen_addsi3 (op2, XEXP (addr1, 0), GEN_INT (4)));
+ emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
}
else
@@ -2657,7 +2659,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
(clobber (match_operand:SI 2 "" ""))]
- "TARGET_32BIT && reload_completed"
+ "!TARGET_POWERPC64 && reload_completed"
[(const_int 0)]
"
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 724d65e..bcc86bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2009-09-14 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/41331
+ * gcc.target/powerpc/bswap64-4.c: New file to test bswap64 on a
+ -m32 -mpowerpc64 system.
+
2009-09-14 Bernd Schmidt <bernd.schmidt@analog.com>
From Jie Zhang <jie.zhang@analog.com>:
diff --git a/gcc/testsuite/gcc.target/powerpc/bswap64-4.c b/gcc/testsuite/gcc.target/powerpc/bswap64-4.c
new file mode 100644
index 0000000..074780c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bswap64-4.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-O2 -mpowerpc64" } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-final { scan-assembler-times "lwbrx" 2 } } */
+/* { dg-final { scan-assembler-times "stwbrx" 2 } } */
+
+long long swap_load (long long *a) { return __builtin_bswap64 (*a); }
+long long swap_reg (long long a) { return __builtin_bswap64 (a); }
+void swap_store (long long *a, long long b) { *a = __builtin_bswap64 (b); }