aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2006-01-11 00:07:16 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2006-01-11 00:07:16 +0000
commit5401050bd5d50fd5d66a378afe4f6eda697d5484 (patch)
treea957155246dc29dc5494f727934fd6001f0f94b6
parent7d0720375952abd2c48d95f4cf752eff7d732e48 (diff)
downloadgcc-5401050bd5d50fd5d66a378afe4f6eda697d5484.zip
gcc-5401050bd5d50fd5d66a378afe4f6eda697d5484.tar.gz
gcc-5401050bd5d50fd5d66a378afe4f6eda697d5484.tar.bz2
re PR target/20754 (ACATS cxg1005 fails at runtime on hppa-linux)
PR target/20754 * pa.md: Create separate 32 and 64-bit move patterns for SI, DI, SF and DF modes. Add alternatives to copy between general and floating point registers to the 32-bit patterns. * pa-64.h (SECONDARY_MEMORY_NEEDED_RTX): Delete undefine. * pa.h (SECONDARY_MEMORY_NEEDED_RTX): Delete define. (SECONDARY_MEMORY_NEEDED): Secondary memory is only needed when generating 64-bit code. * pa.c (output_move_double): Handle copies between general and floating registers. From-SVN: r109557
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/pa/pa-64.h4
-rw-r--r--gcc/config/pa/pa.c19
-rw-r--r--gcc/config/pa/pa.h17
-rw-r--r--gcc/config/pa/pa.md93
5 files changed, 116 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b74c09f..e4a8ce86 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2006-01-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/20754
+ * pa.md: Create separate 32 and 64-bit move patterns for SI, DI, SF
+ and DF modes. Add alternatives to copy between general and floating
+ point registers to the 32-bit patterns.
+ * pa-64.h (SECONDARY_MEMORY_NEEDED_RTX): Delete undefine.
+ * pa.h (SECONDARY_MEMORY_NEEDED_RTX): Delete define.
+ (SECONDARY_MEMORY_NEEDED): Secondary memory is only needed when
+ generating 64-bit code.
+ * pa.c (output_move_double): Handle copies between general and
+ floating registers.
+
2006-01-10 Stuart Hastings <stuart@apple.com>
* gcc/config/i386/i386.md (set_got): Update.
diff --git a/gcc/config/pa/pa-64.h b/gcc/config/pa/pa-64.h
index a59b4e0..750b13c 100644
--- a/gcc/config/pa/pa-64.h
+++ b/gcc/config/pa/pa-64.h
@@ -70,10 +70,6 @@ Boston, MA 02110-1301, USA. */
relocs which appear in stabs. */
#undef DBX_DEBUGGING_INFO
-/* We want the compiler to select a suitable secondary memory location.
- ?!? This may not work reliably. Keep an eye out for problems. */
-#undef SECONDARY_MEMORY_NEEDED_RTX
-
/* ?!? This needs to be made compile-time selectable.
The PA64 runtime model has arguments that grow to higher addresses
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index d4800fe..0d8ec24 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -2209,6 +2209,25 @@ output_move_double (rtx *operands)
supposed to allow to happen. */
gcc_assert (optype0 == REGOP || optype1 == REGOP);
+ /* Handle copies between general and floating registers. */
+
+ if (optype0 == REGOP && optype1 == REGOP
+ && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1]))
+ {
+ if (FP_REG_P (operands[0]))
+ {
+ output_asm_insn ("{stws|stw} %1,-16(%%sp)", operands);
+ output_asm_insn ("{stws|stw} %R1,-12(%%sp)", operands);
+ return "{fldds|fldd} -16(%%sp),%0";
+ }
+ else
+ {
+ output_asm_insn ("{fstds|fstd} %1,-16(%%sp)", operands);
+ output_asm_insn ("{ldws|ldw} -16(%%sp),%0", operands);
+ return "{ldws|ldw} -12(%%sp),%R0";
+ }
+ }
+
/* Handle auto decrementing and incrementing loads and stores
specifically, since the structure of the function doesn't work
for them without major modification. Do it better when we learn
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index a98d1cd..c29a876 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -531,14 +531,15 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
reg_classes_intersect_p ((CLASS), FP_REGS)
/* On the PA it is not possible to directly move data between
- GENERAL_REGS and FP_REGS. */
-#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \
- || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1))
-
-/* Return the stack location to use for secondary memory needed reloads. */
-#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
- gen_rtx_MEM (MODE, gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-16)))
+ GENERAL_REGS and FP_REGS. On the 32-bit port, we use the
+ location at SP-16. We don't expose this location in the RTL to
+ avoid scheduling related problems. For example, the store and
+ load could be separated by a call to a pure or const function
+ which has no frame and uses SP-16. */
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
+ (TARGET_64BIT \
+ && (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \
+ || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1)))
/* Stack layout; function entry, exit and calling. */
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 556c941..b51feb0 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -2307,12 +2307,41 @@
(define_insn ""
[(set (match_operand:SI 0 "move_dest_operand"
+ "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,r,f")
+ (match_operand:SI 1 "move_src_operand"
+ "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,f,r"))]
+ "(register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode))
+ && !TARGET_SOFT_FLOAT
+ && !TARGET_64BIT"
+ "@
+ ldw RT'%A1,%0
+ copy %1,%0
+ ldi %1,%0
+ ldil L'%1,%0
+ {zdepi|depwi,z} %Z1,%0
+ ldw%M1 %1,%0
+ stw%M0 %r1,%0
+ mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
+ fcpy,sgl %f1,%0
+ fldw%F1 %1,%0
+ fstw%F0 %1,%0
+ {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
+ {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
+ [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,move,move")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
+
+(define_insn ""
+ [(set (match_operand:SI 0 "move_dest_operand"
"=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
(match_operand:SI 1 "move_src_operand"
"A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))
- && !TARGET_SOFT_FLOAT"
+ && !TARGET_SOFT_FLOAT
+ && TARGET_64BIT"
"@
ldw RT'%A1,%0
copy %1,%0
@@ -3840,9 +3869,9 @@
(define_insn ""
[(set (match_operand:DF 0 "move_dest_operand"
- "=f,*r,Q,?o,?Q,f,*r,*r")
+ "=f,*r,Q,?o,?Q,f,*r,*r,r,f")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
- "fG,*rG,f,*r,*r,RQ,o,RQ"))]
+ "fG,*rG,f,*r,*r,RQ,o,RQ,f,r"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
&& !(GET_CODE (operands[1]) == CONST_DOUBLE
@@ -3851,13 +3880,15 @@
&& !TARGET_SOFT_FLOAT"
"*
{
- if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
- || operands[1] == CONST0_RTX (DFmode))
+ if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
+ || operands[1] == CONST0_RTX (DFmode))
+ && !(REG_P (operands[0]) && REG_P (operands[1])
+ && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
return output_fp_move_double (operands);
return output_move_double (operands);
}"
- [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
- (set_attr "length" "4,8,4,8,16,4,8,16")])
+ [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,move,move")
+ (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
(define_insn ""
[(set (match_operand:DF 0 "indexed_memory_operand" "=R")
@@ -4012,9 +4043,9 @@
(define_insn ""
[(set (match_operand:DF 0 "move_dest_operand"
- "=r,?o,?Q,r,r")
+ "=r,?o,?Q,r,r,r,f")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
- "rG,r,r,o,RQ"))]
+ "rG,r,r,o,RQ,f,r"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
&& !TARGET_64BIT
@@ -4023,8 +4054,8 @@
{
return output_move_double (operands);
}"
- [(set_attr "type" "move,store,store,load,load")
- (set_attr "length" "8,8,16,8,16")])
+ [(set_attr "type" "move,store,store,load,load,move,move")
+ (set_attr "length" "8,8,16,8,16,12,12")])
(define_insn ""
[(set (match_operand:DF 0 "move_dest_operand"
@@ -4154,22 +4185,25 @@
(define_insn ""
[(set (match_operand:DI 0 "move_dest_operand"
- "=r,o,Q,r,r,r,*f,*f,T")
+ "=r,o,Q,r,r,r,*f,*f,T,r,f")
(match_operand:DI 1 "general_operand"
- "rM,r,r,o*R,Q,i,*fM,RT,*f"))]
+ "rM,r,r,o*R,Q,i,*fM,RT,*f,f,r"))]
"(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))
&& !TARGET_64BIT
&& !TARGET_SOFT_FLOAT"
"*
{
- if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
- || (operands[1] == CONST0_RTX (DImode)))
+ if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
+ || operands[1] == CONST0_RTX (DFmode))
+ && !(REG_P (operands[0]) && REG_P (operands[1])
+ && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
return output_fp_move_double (operands);
return output_move_double (operands);
}"
- [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
- (set_attr "length" "8,8,16,8,16,16,4,4,4")])
+ [(set_attr "type"
+ "move,store,store,load,load,multi,fpalu,fpload,fpstore,move,move")
+ (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
(define_insn ""
[(set (match_operand:DI 0 "move_dest_operand"
@@ -4380,12 +4414,35 @@
(define_insn ""
[(set (match_operand:SF 0 "move_dest_operand"
+ "=f,!*r,f,*r,Q,Q,r,f")
+ (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
+ "fG,!*rG,RQ,RQ,f,*rG,f,r"))]
+ "(register_operand (operands[0], SFmode)
+ || reg_or_0_operand (operands[1], SFmode))
+ && !TARGET_SOFT_FLOAT
+ && !TARGET_64BIT"
+ "@
+ fcpy,sgl %f1,%0
+ copy %r1,%0
+ fldw%F1 %1,%0
+ ldw%M1 %1,%0
+ fstw%F0 %1,%0
+ stw%M0 %r1,%0
+ {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
+ {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
+ [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,move,move")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4,4,4,4,4,4,8,8")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "move_dest_operand"
"=f,!*r,f,*r,Q,Q")
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
"fG,!*rG,RQ,RQ,f,*rG"))]
"(register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode))
- && !TARGET_SOFT_FLOAT"
+ && !TARGET_SOFT_FLOAT
+ && TARGET_64BIT"
"@
fcpy,sgl %f1,%0
copy %r1,%0