Hello! While looking in this area, I've noticed that there are constraints that allow wide immediate operands that result in unsupported immediate->memory moves on 64bit targets. Since these immediates have to be limited to 32bits, we have to use C constraint that allows only all-bits-zero 0.0 FP value.
2017-03-03 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (*pushtf): Change *roF constraint to *roC. (*pushxf): Limit oF constraint to 32bit targets and add oC constraint for 64bit targets. (pushxf splitter): Use PUSH_ROUNDING to calculate stack adjustment. (*pushdf): Change rmF constraint to rmC. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32} and committed. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 245874) +++ config/i386/i386.md (working copy) @@ -2992,7 +2992,7 @@ (define_insn "*pushtf" [(set (match_operand:TF 0 "push_operand" "=<,<") - (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))] + (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))] "TARGET_64BIT || TARGET_SSE" { /* This insn should be already split before reg-stack. */ @@ -3046,17 +3046,18 @@ (symbol_ref "true")))]) (define_insn "*pushxf" - [(set (match_operand:XF 0 "push_operand" "=<,<,<,<") - (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))] + [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<") + (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))] "" { /* This insn should be already split before reg-stack. */ gcc_unreachable (); } - [(set_attr "type" "multi") - (set_attr "unit" "i387,*,*,*") + [(set_attr "isa" "*,*,*,nox64,x64") + (set_attr "type" "multi") + (set_attr "unit" "i387,*,*,*,*") (set (attr "mode") - (cond [(eq_attr "alternative" "1,2,3") + (cond [(eq_attr "alternative" "1,2,3,4") (if_then_else (match_test "TARGET_64BIT") (const_string "DI") (const_string "SI")) @@ -3075,7 +3076,7 @@ [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) (set (match_dup 0) (match_dup 1))] { - operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode)); + operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode))); /* Preserve memory attributes. */ operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); }) @@ -3082,7 +3083,7 @@ (define_insn "*pushdf" [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<") - (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))] + (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))] "" { /* This insn should be already split before reg-stack. */