From 5401050bd5d50fd5d66a378afe4f6eda697d5484 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Wed, 11 Jan 2006 00:07:16 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 13 ++++++ gcc/config/pa/pa-64.h | 4 -- gcc/config/pa/pa.c | 19 +++++++++ gcc/config/pa/pa.h | 17 ++++---- gcc/config/pa/pa.md | 93 ++++++++++++++++++++++++++++++++++--------- 5 files changed, 116 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b74c09f64b7e..e4a8ce86f5e4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2006-01-10 John David Anglin + + 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 * 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 a59b4e04af2f..750b13ca0329 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 d4800fee44e5..0d8ec24c1f9e 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 a98d1cdda023..c29a8764eab0 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 556c941a5a67..b51feb0ee162 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -2305,6 +2305,34 @@ DONE; }") +(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") @@ -2312,7 +2340,8 @@ "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" @@ -4378,6 +4412,28 @@ DONE; }") +(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") @@ -4385,7 +4441,8 @@ "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 -- 2.47.2