+2015-10-05 Michael Meissner <meissner@linux.vnet.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
+
+ PR target/67808
+ * config/rs6000/rs6000.md (extenddftf2): In the expander, only
+ allow registers, but provide insns for the combiner to create for
+ loads from memory. Separate VSX code from non-VSX code. For
+ non-VSX code, combine extenddftf2_fprs into extenddftf2 and rename
+ externaldftf2_internal to externaldftf2_fprs. Reorder constraints
+ so that registers come before memory operations. Drop support from
+ converting DFmode to TFmode, if the DFmode value is in a GPR
+ register.
+ (extenddftf2_fprs): Likewise.
+ (extenddftf2_internal): Likewise.
+ (extenddftf2_vsx): Likewise.
+ (extendsftf2): In the expander, only allow registers, but provide
+ insns for the combiner to create for stores and loads.
+
2015-10-06 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* varasm.c (default_elf_asm_named_section): Remove ATTRIBUTE_UNUSED
[(set_attr "length" "20,20,16")])
(define_expand "extenddftf2"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (float_extend:TF (match_operand:DF 1 "input_operand" "")))]
+ [(set (match_operand:TF 0 "gpc_reg_operand" "")
+ (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
&& TARGET_LONG_DOUBLE_128"
{
rs6000_expand_float128_convert (operands[0], operands[1], false);
else if (TARGET_E500_DOUBLE)
emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
+ else if (TARGET_VSX)
+ emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
else
- emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
+ {
+ rtx zero = gen_reg_rtx (DFmode);
+ rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
+ emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
+ }
DONE;
})
-(define_expand "extenddftf2_fprs"
- [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (float_extend:TF (match_operand:DF 1 "input_operand" "")))
- (use (match_dup 2))])]
- "!TARGET_IEEEQUAD
- && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
- && TARGET_LONG_DOUBLE_128"
+;; Allow memory operands for the source to be created by the combiner.
+(define_insn_and_split "extenddftf2_fprs"
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d,&d")
+ (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
+ (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
+ "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+ && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 4) (match_dup 2))]
{
- /* VSX can create 0.0 directly, otherwise let rs6000_emit_move create
- the proper constant. */
- if (TARGET_VSX)
- operands[2] = CONST0_RTX (DFmode);
- else
- {
- operands[2] = gen_reg_rtx (DFmode);
- rs6000_emit_move (operands[2], CONST0_RTX (DFmode), DFmode);
- }
+ const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
+
+ operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
+ operands[4] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
})
-(define_insn_and_split "*extenddftf2_internal"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,ws,d,&d")
- (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,md")))
- (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,j,m,d"))]
- "!TARGET_IEEEQUAD
- && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
- && TARGET_LONG_DOUBLE_128"
+(define_insn_and_split "extenddftf2_vsx"
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d")
+ (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
+ "TARGET_LONG_DOUBLE_128 && TARGET_VSX && !TARGET_IEEEQUAD"
"#"
"&& reload_completed"
- [(pc)]
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 3) (match_dup 4))]
{
const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
- emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
- operands[1]);
- emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
- operands[2]);
- DONE;
+
+ operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
+ operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
+ operands[4] = CONST0_RTX (DFmode);
})
(define_expand "extendsftf2"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ [(set (match_operand:TF 0 "gpc_reg_operand" "")
(float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT
&& (TARGET_FPRS || TARGET_E500_DOUBLE)