diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index f2b10afe35b..6c50b75a97f 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -248,6 +248,9 @@ ;; Is copying of this instruction disallowed? (define_attr "cannot_copy" "no,yes" (const_string "no")) +;; Does this insn require indexed or indirect (x-form) memory addressing? +(define_attr "xform_memory" "no,yes" (const_string "no")) + ;; Length of the instruction (in bytes). (define_attr "length" "" (const_int 4)) @@ -5174,8 +5177,11 @@ ;; Conversions to and from floating-point. -; We don't define lfiwax/lfiwzx with the normal definition, because we -; don't want to support putting SImode in FPR registers. +;; We don't define lfiwax/lfiwzx with the normal definition. On ISA 2.05/2.06 +;; (power6/power7), SImode is not allowed in FPR registers. On ISA 2.07 and +;; above, SImode is allowed, but we prefer to have a special definition so that +;; the register allocator isn't tempted to load the value into a GPR and use +;; direct move. (define_insn "lfiwax" [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK") (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")] @@ -5186,7 +5192,8 @@ lxsiwax %x0,%y1 mtvsrwa %x0,%1 vextsw2d %0,%1" - [(set_attr "type" "fpload,fpload,mffgpr,vecexts")]) + [(set_attr "type" "fpload,fpload,mffgpr,vecexts") + (set_attr "xform_memory" "yes")]) ; This split must be run before register allocation because it allocates the ; memory slot that is needed to move values to/from the FPR. We don't allocate @@ -5217,7 +5224,8 @@ tmp = gen_reg_rtx (DImode); if (MEM_P (src)) { - src = rs6000_force_indexed_or_indirect_mem (src); + if (!TARGET_OPT_XFORM) + src = rs6000_force_indexed_or_indirect_mem (src); emit_insn (gen_lfiwax (tmp, src)); } else @@ -5231,7 +5239,8 @@ DONE; } [(set_attr "length" "12") - (set_attr "type" "fpload")]) + (set_attr "type" "fpload") + (set_attr "xform_memory" "yes")]) (define_insn_and_split "floatsi<mode>2_lfiwax_mem" [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") @@ -5255,7 +5264,8 @@ DONE; } [(set_attr "length" "8") - (set_attr "type" "fpload")]) + (set_attr "type" "fpload") + (set_attr "xform_memory" "yes")]) (define_insn "lfiwzx" [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK") @@ -5267,7 +5277,8 @@ lxsiwzx %x0,%y1 mtvsrwz %x0,%1 xxextractuw %x0,%x1,4" - [(set_attr "type" "fpload,fpload,mftgpr,vecexts")]) + [(set_attr "type" "fpload,fpload,mftgpr,vecexts") + (set_attr "xform_memory" "yes")]) (define_insn_and_split "floatunssi<mode>2_lfiwzx" [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") @@ -5292,7 +5303,8 @@ tmp = gen_reg_rtx (DImode); if (MEM_P (src)) { - src = rs6000_force_indexed_or_indirect_mem (src); + if (!TARGET_OPT_XFORM) + src = rs6000_force_indexed_or_indirect_mem (src); emit_insn (gen_lfiwzx (tmp, src)); } else @@ -5306,7 +5318,8 @@ DONE; } [(set_attr "length" "12") - (set_attr "type" "fpload")]) + (set_attr "type" "fpload") + (set_attr "xform_memory" "yes")]) (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") @@ -5546,7 +5559,8 @@ emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); DONE; -}) +} + [(set_attr "xform_memory" "yes")]) (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") @@ -5591,7 +5605,8 @@ emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); DONE; -}) +} + [(set_attr "xform_memory" "yes")]) (define_expand "fix_trunc<mode>si2" [(set (match_operand:SI 0 "gpc_reg_operand") @@ -5638,7 +5653,8 @@ emit_insn (gen_fctiwz_<mode> (tmp, src)); if (MEM_P (dest)) { - dest = rs6000_force_indexed_or_indirect_mem (dest); + if (!TARGET_OPT_XFORM) + dest = rs6000_force_indexed_or_indirect_mem (dest); emit_insn (gen_stfiwx (dest, tmp)); DONE; } @@ -5657,7 +5673,8 @@ } } [(set_attr "length" "12") - (set_attr "type" "fp")]) + (set_attr "type" "fp") + (set_attr "xform_memory" "yes")]) (define_insn_and_split "fix_trunc<mode>si2_internal" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") @@ -5750,7 +5767,8 @@ operands[3] = (<QHSI:MODE>mode == SImode ? operands[2] : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2]))); -}) +} + [(set_attr "xform_memory" "yes")]) (define_expand "fixuns_trunc<mode>si2" [(set (match_operand:SI 0 "gpc_reg_operand") @@ -5785,7 +5803,8 @@ emit_insn (gen_fctiwuz_<mode> (tmp, src)); if (MEM_P (dest)) { - dest = rs6000_force_indexed_or_indirect_mem (dest); + if (!TARGET_OPT_XFORM) + dest = rs6000_force_indexed_or_indirect_mem (dest); emit_insn (gen_stfiwx (dest, tmp)); DONE; } @@ -5804,7 +5823,8 @@ } } [(set_attr "length" "12") - (set_attr "type" "fp")]) + (set_attr "type" "fp") + (set_attr "xform_memory" "yes")]) (define_insn "fixuns_trunc<mode>di2" [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") @@ -14248,10 +14268,8 @@ { if (GET_CODE (operands[2]) == SCRATCH) operands[2] = gen_reg_rtx (DImode); - - if (MEM_P (operands[1])) - operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); -}) +} + [(set_attr "xform_memory" "yes")]) (define_insn_and_split "float<QHI:mode><IEEE128:mode>2" [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") @@ -14314,10 +14332,8 @@ { if (GET_CODE (operands[2]) == SCRATCH) operands[2] = gen_reg_rtx (DImode); - - if (MEM_P (operands[1])) - operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); -}) +} + [(set_attr "xform_memory" "yes")]) (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") |