;; The only conversions we will do will be when storing to memory. In that
;; case, we will use the "frsp" instruction before storing.
;;
+;; SFmode values are stored in DFmode registers with the same format as
+;; DFmode values, so float_extend is a no-op: treat as paradoxical subreg
+;; using define_expand and define_split if made by combine.
+;;
;; Note that when we store into a single-precision memory location, we need to
;; use the frsp insn first. If the register being stored isn't dead, we
;; need a scratch register for the frsp. But this is difficult when the store
;; this case, we just lose precision that we would have otherwise gotten but
;; is not guaranteed. Perhaps this should be tightened up at some point.
-(define_insn "extendsfdf2"
+(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
- (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))]
+ (match_operand:SF 1 "gpc_reg_operand" "f"))]
""
- "*
+ "
{
- if (REGNO (operands[0]) == REGNO (operands[1]))
- return \"\";
- else
- return \"fmr %0,%1\";
-}"
- [(set_attr "type" "fp")])
+ if (GET_CODE (operands[1]) == SUBREG)
+ operands[1] = force_reg (SFmode, operands[1]);
+ operands[1] = gen_rtx (SUBREG, DFmode, operands[1], 0);
+}")
+
+(define_split
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "")))]
+ "GET_CODE (operands[1]) != SUBREG"
+ [(set (match_dup 0) (match_dup 1))]
+ "
+{
+ operands[1] = gen_rtx (SUBREG, DFmode, operands[1], 0);
+}")
(define_insn "truncdfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")