From 0ec259edcd7e739f9cbd2609febb18497ce08c4d Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 22 Mar 2001 21:43:26 +0100 Subject: [PATCH] i386.md (pushsi, [...]): Disable. * i386.md (pushsi, pushsi2_prologue): Disable. (pushsi2_rex64): New. (movabs?i_1_rex64, movabs?i_2_rex64): New. (movqi_ext_1): Disable for 64bit. (movqi_ext_1_rex64): New. (pushdi2_rex64): New pattern, peep2s and splitter. (pushdi2_prologue_rex64): New pattern. (popdi1_epilogue_rex64, popdi1, movdi_xor_rex64, movdi_or_rex64): Likewise. (movdi splitters): Disable for 64bit. (movdi_1_rex64): New pattern, peep2s and splitters. (swapdi): New pattern. (pushsf): Disable for 64bit. (pushsf_rex64): New pattern and splitter. (pushdf_nointeger): Disable for 64bit. (pushdf_integer): Handle the 64bit case. (pushtf): Likewise; update splitters. From-SVN: r40758 --- gcc/ChangeLog | 20 ++ gcc/config/i386/i386.md | 475 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 475 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73afd2179c1..ce95c886796 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +Thu Mar 22 21:41:16 CET 2001 Jan Hubicka + + * i386.md (pushsi, pushsi2_prologue): Disable. + (pushsi2_rex64): New. + (movabs?i_1_rex64, movabs?i_2_rex64): New. + (movqi_ext_1): Disable for 64bit. + (movqi_ext_1_rex64): New. + (pushdi2_rex64): New pattern, peep2s and splitter. + (pushdi2_prologue_rex64): New pattern. + (popdi1_epilogue_rex64, popdi1, movdi_xor_rex64, movdi_or_rex64): + Likewise. + (movdi splitters): Disable for 64bit. + (movdi_1_rex64): New pattern, peep2s and splitters. + (swapdi): New pattern. + (pushsf): Disable for 64bit. + (pushsf_rex64): New pattern and splitter. + (pushdf_nointeger): Disable for 64bit. + (pushdf_integer): Handle the 64bit case. + (pushtf): Likewise; update splitters. + 2001-03-22 Richard Henderson * mkconfig.sh: Include insn-flags.h. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2f0cd1aa624..0a2600984c4 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1622,16 +1622,25 @@ (define_insn "*pushsi2" [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] - "" + "!TARGET_64BIT" "push{l}\\t%1" [(set_attr "type" "push") (set_attr "mode" "SI")]) +;; For 64BIT abi we always round up to 8 bytes. +(define_insn "*pushsi2_rex64" + [(set (match_operand:SI 0 "push_operand" "=X") + (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] + "TARGET_64BIT" + "push{q}\\t%q1" + [(set_attr "type" "push") + (set_attr "mode" "SI")]) + (define_insn "*pushsi2_prologue" [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "general_no_elim_operand" "ri*m")) (set (reg:SI 6) (reg:SI 6))] - "" + "!TARGET_64BIT" "push{l}\\t%1" [(set_attr "type" "push") (set_attr "mode" "SI")]) @@ -1715,6 +1724,38 @@ (set_attr "modrm" "0,*,0,*,*,*") (set_attr "mode" "SI")]) +;; Stores and loads of ax to arbitary constant address. +;; We fake an second form of instruction to force reload to load address +;; into register when rax is not available +(define_insn "*movabssi_1_rex64" + [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r")) + (match_operand:SI 1 "nonmemory_operand" "a,er,i"))] + "TARGET_64BIT" + "@ + movabs{l}\\t{%1, %P0|%P0, %1} + mov{l}\\t{%1, %a0|%a0, %1} + movabs{l}\\t{%1, %a0|%a0, %1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*,*") + (set_attr "length_address" "8,0,0") + (set_attr "length_immediate" "0,*,*") + (set_attr "memory" "store") + (set_attr "mode" "SI")]) + +(define_insn "*movabssi_2_rex64" + [(set (match_operand:SI 0 "register_operand" "=a,r") + (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] + "TARGET_64BIT" + "@ + movabs{l}\\t{%P1, %0|%0, %P1} + mov{l}\\t{%a1, %0|%0, %a1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*") + (set_attr "length_address" "8,0") + (set_attr "length_immediate" "0") + (set_attr "memory" "load") + (set_attr "mode" "SI")]) + (define_insn "*swapsi" [(set (match_operand:SI 0 "register_operand" "+r") (match_operand:SI 1 "register_operand" "+r")) @@ -1796,6 +1837,38 @@ (const_string "HI"))) (set_attr "modrm" "0,*,*,0,*,*")]) +;; Stores and loads of ax to arbitary constant address. +;; We fake an second form of instruction to force reload to load address +;; into register when rax is not available +(define_insn "*movabshi_1_rex64" + [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r")) + (match_operand:HI 1 "nonmemory_operand" "a,er,i"))] + "TARGET_64BIT" + "@ + movabs{w}\\t{%1, %P0|%P0, %1} + mov{w}\\t{%1, %a0|%a0, %1} + movabs{w}\\t{%1, %a0|%a0, %1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*,*") + (set_attr "length_address" "8,0,0") + (set_attr "length_immediate" "0,*,*") + (set_attr "memory" "store") + (set_attr "mode" "HI")]) + +(define_insn "*movabshi_2_rex64" + [(set (match_operand:HI 0 "register_operand" "=a,r") + (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] + "TARGET_64BIT" + "@ + movabs{w}\\t{%P1, %0|%0, %P1} + mov{w}\\t{%a1, %0|%0, %a1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*") + (set_attr "length_address" "8,0") + (set_attr "length_immediate" "0") + (set_attr "memory" "load") + (set_attr "mode" "HI")]) + (define_insn "*swaphi_1" [(set (match_operand:HI 0 "register_operand" "+r") (match_operand:HI 1 "register_operand" "+r")) @@ -2024,11 +2097,11 @@ (set_attr "mode" "SI")]) (define_insn "*movqi_extv_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r") - (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q") + [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") + (sign_extract:QI (match_operand:SI 1 "ext_register_operand" "Q,Q") (const_int 8) (const_int 8)))] - "" + "!TARGET_64BIT" "* { switch (get_attr_type (insn)) @@ -2051,6 +2124,66 @@ (const_string "SI") (const_string "QI")))]) +(define_insn "*movqi_extv_1_rex64" + [(set (match_operand:QI 0 "register_operand" "=Q,?R") + (sign_extract:QI (match_operand:SI 1 "ext_register_operand" "Q,Q") + (const_int 8) + (const_int 8)))] + "TARGET_64BIT" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_IMOVX: + return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\"; + default: + return \"mov{b}\\t{%h1, %0|%0, %h1}\"; + } +}" + [(set (attr "type") + (if_then_else (and (match_operand:QI 0 "register_operand" "") + (ior (not (match_operand:QI 0 "q_regs_operand" "")) + (ne (symbol_ref "TARGET_MOVX") + (const_int 0)))) + (const_string "imovx") + (const_string "imov"))) + (set (attr "mode") + (if_then_else (eq_attr "type" "imovx") + (const_string "SI") + (const_string "QI")))]) + +;; Stores and loads of ax to arbitary constant address. +;; We fake an second form of instruction to force reload to load address +;; into register when rax is not available +(define_insn "*movabsqi_1_rex64" + [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r")) + (match_operand:QI 1 "nonmemory_operand" "a,er,i"))] + "TARGET_64BIT" + "@ + movabs{q}\\t{%1, %P0|%P0, %1} + mov{q}\\t{%1, %a0|%a0, %1} + movabs{q}\\t{%1, %a0|%a0, %1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*,*") + (set_attr "length_address" "8,0,0") + (set_attr "length_immediate" "0,*,*") + (set_attr "memory" "store") + (set_attr "mode" "QI")]) + +(define_insn "*movabsqi_2_rex64" + [(set (match_operand:QI 0 "register_operand" "=a,r") + (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] + "TARGET_64BIT" + "@ + movabs{q}\\t{%P1, %0|%0, %P1} + mov{q}\\t{%a1, %0|%0, %a1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*") + (set_attr "length_address" "8,0") + (set_attr "length_immediate" "0") + (set_attr "memory" "load") + (set_attr "mode" "QI")]) + (define_insn "*movsi_extzv_1" [(set (match_operand:SI 0 "register_operand" "=R") (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") @@ -2160,6 +2293,117 @@ "!TARGET_64BIT" "#") +(define_insn "pushdi2_rex64" + [(set (match_operand:DI 0 "push_operand" "=<,!<") + (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] + "TARGET_64BIT" + "@ + push{q}\\t%1 + #" + [(set_attr "type" "push,multi") + (set_attr "mode" "DI")]) + +;; Convert impossible pushes of immediate to existing instructions. +;; First try to get scratch register and go trought it. In case this +;; fails, push sign extended lower part first and then overwrite +;; upper part by 32bit move. +(define_peephole2 + [(match_scratch:DI 2 "r") + (set (match_operand:DI 0 "push_operand" "") + (match_operand:DI 1 "immediate_operand" ""))] + "TARGET_64BIT && !symbolic_operand (operands[1], DImode) + && !x86_64_immediate_operand (operands[1], DImode)" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (match_dup 2))] + "") + +;; We need to define this as both peepholer and splitter for case +;; peephole2 pass is not run. +(define_peephole2 + [(set (match_operand:DI 0 "push_operand" "") + (match_operand:DI 1 "immediate_operand" ""))] + "TARGET_64BIT && !symbolic_operand (operands[1], DImode) + && !x86_64_immediate_operand (operands[1], DImode) && 1" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + "split_di (operands + 1, 1, operands + 2, operands + 3); + operands[1] = gen_lowpart (DImode, operands[2]); + operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, + GEN_INT (4))); + ") + +(define_split + [(set (match_operand:DI 0 "push_operand" "") + (match_operand:DI 1 "immediate_operand" ""))] + "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2)) + && !symbolic_operand (operands[1], DImode) + && !x86_64_immediate_operand (operands[1], DImode)" + [(set (match_dup 0) (match_dup 1)) + (set (match_dup 2) (match_dup 3))] + "split_di (operands + 1, 1, operands + 2, operands + 3); + operands[1] = gen_lowpart (DImode, operands[2]); + operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, + GEN_INT (4))); + ") + +(define_insn "*pushdi2_prologue_rex64" + [(set (match_operand:DI 0 "push_operand" "=<") + (match_operand:DI 1 "general_no_elim_operand" "re*m")) + (set (reg:DI 6) (reg:DI 6))] + "TARGET_64BIT" + "push{q}\\t%1" + [(set_attr "type" "push") + (set_attr "mode" "DI")]) + +(define_insn "*popdi1_epilogue_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") + (mem:DI (reg:DI 7))) + (set (reg:DI 7) + (plus:DI (reg:DI 7) (const_int 8))) + (set (reg:DI 6) (reg:DI 6))] + "TARGET_64BIT" + "pop{q}\\t%0" + [(set_attr "type" "pop") + (set_attr "mode" "DI")]) + +(define_insn "popdi1" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") + (mem:DI (reg:DI 7))) + (set (reg:DI 7) + (plus:DI (reg:DI 7) (const_int 8)))] + "TARGET_64BIT" + "pop{q}\\t%0" + [(set_attr "type" "pop") + (set_attr "mode" "DI")]) + +(define_insn "*movdi_xor_rex64" + [(set (match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "const0_operand" "i")) + (clobber (reg:CC 17))] + "reload_completed && (!TARGET_USE_MOV0 || optimize_size) + && TARGET_64BIT" + "xor{l}\\t{%k0, %k0|%k0, %k0}" + [(set_attr "type" "alu1") + (set_attr "mode" "SI") + (set_attr "length_immediate" "0")]) + +(define_insn "*movdi_or_rex64" + [(set (match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "const_int_operand" "i")) + (clobber (reg:CC 17))] + "reload_completed && GET_CODE (operands[1]) == CONST_INT + && TARGET_64BIT + && INTVAL (operands[1]) == -1 + && (TARGET_PENTIUM || optimize_size)" + "* +{ + operands[1] = constm1_rtx; + return \"or{q}\\t{%1, %0|%0, %1}\"; +}" + [(set_attr "type" "alu1") + (set_attr "mode" "DI") + (set_attr "length_immediate" "1")]) + (define_insn "*movdi_2" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y") (match_operand:DI 1 "general_operand" "riFo,riF,*y,m"))] @@ -2175,7 +2419,7 @@ (define_split [(set (match_operand:DI 0 "push_operand" "") (match_operand:DI 1 "general_operand" ""))] - "reload_completed && ! MMX_REG_P (operands[1]) && !TARGET_64BIT" + "!TARGET_64BIT && reload_completed && ! MMX_REG_P (operands[1])" [(const_int 0)] "if (!ix86_split_long_move (operands)) abort (); DONE;") @@ -2183,10 +2427,135 @@ (define_split [(set (match_operand:DI 0 "nonimmediate_operand" "") (match_operand:DI 1 "general_operand" ""))] - "reload_completed && ! MMX_REG_P (operands[0]) && ! MMX_REG_P (operands[1])" + "!TARGET_64BIT && reload_completed && ! MMX_REG_P (operands[0]) + && ! MMX_REG_P (operands[1])" [(set (match_dup 2) (match_dup 5)) (set (match_dup 3) (match_dup 6))] "if (ix86_split_long_move (operands)) DONE;") + +(define_insn "*movdi_1_rex64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,*m,*Y") + (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*m"))] + "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) + && TARGET_64BIT" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_SSE: + case TYPE_MMX: + return \"movd\\t{%1, %0|%0, %1}\"; + case TYPE_MULTI: + return \"#\"; + case TYPE_LEA: + return \"lea{q}\\t{%a1, %0|%0, %a1}\"; + default: + if (flag_pic && SYMBOLIC_CONST (operands[1])) + abort (); + if (get_attr_mode (insn) == MODE_SI) + return \"mov{l}\\t{%k1, %k0|%k0, %k1}\"; + else if (which_alternative == 2) + return \"movabs{q}\\t{%1, %0|%0, %1}\"; + else + return \"mov{q}\\t{%1, %0|%0, %1}\"; + } +}" + [(set (attr "type") + (cond [(eq_attr "alternative" "5,6") + (const_string "mmx") + (eq_attr "alternative" "7,8") + (const_string "sse") + (eq_attr "alternative" "4") + (const_string "multi") + (and (ne (symbol_ref "flag_pic") (const_int 0)) + (match_operand:DI 1 "symbolic_operand" "")) + (const_string "lea") + ] + (const_string "imov"))) + (set_attr "modrm" "*,0,0,*,*,*,*,*,*") + (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*") + (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI")]) + +;; Stores and loads of ax to arbitary constant address. +;; We fake an second form of instruction to force reload to load address +;; into register when rax is not available +(define_insn "*movabsdi_1_rex64" + [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r")) + (match_operand:DI 1 "nonmemory_operand" "a,er,i"))] + "TARGET_64BIT" + "@ + movabs{q}\\t{%1, %P0|%P0, %1} + mov{q}\\t{%1, %a0|%a0, %1} + movabs{q}\\t{%1, %a0|%a0, %1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*,*") + (set_attr "length_address" "8,0,0") + (set_attr "length_immediate" "0,*,*") + (set_attr "memory" "store") + (set_attr "mode" "DI")]) + +(define_insn "*movabsdi_2_rex64" + [(set (match_operand:DI 0 "register_operand" "=a,r") + (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] + "TARGET_64BIT" + "@ + movabs{q}\\t{%P1, %0|%0, %P1} + mov{q}\\t{%a1, %0|%0, %a1}" + [(set_attr "type" "imov") + (set_attr "modrm" "0,*") + (set_attr "length_address" "8,0") + (set_attr "length_immediate" "0") + (set_attr "memory" "load") + (set_attr "mode" "DI")]) + +;; Convert impossible stores of immediate to existing instructions. +;; First try to get scratch register and go trought it. In case this +;; fails, move by 32bit parts. +(define_peephole2 + [(match_scratch:DI 2 "r") + (set (match_operand:DI 0 "memory_operand" "") + (match_operand:DI 1 "immediate_operand" ""))] + "TARGET_64BIT && !symbolic_operand (operands[1], DImode) + && !x86_64_immediate_operand (operands[1], DImode)" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (match_dup 2))] + "") + +;; We need to define this as both peepholer and splitter for case +;; peephole2 pass is not run. +(define_peephole2 + [(set (match_operand:DI 0 "memory_operand" "") + (match_operand:DI 1 "immediate_operand" ""))] + "TARGET_64BIT && !symbolic_operand (operands[1], DImode) + && !x86_64_immediate_operand (operands[1], DImode) && 1" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) (match_dup 5))] + "split_di (operands, 2, operands + 2, operands + 4);") + +(define_split + [(set (match_operand:DI 0 "memory_operand" "") + (match_operand:DI 1 "immediate_operand" ""))] + "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2)) + && !symbolic_operand (operands[1], DImode) + && !x86_64_immediate_operand (operands[1], DImode)" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) (match_dup 5))] + "split_di (operands, 2, operands + 2, operands + 4);") + +(define_insn "*swapdi_rex64" + [(set (match_operand:DI 0 "register_operand" "+r") + (match_operand:DI 1 "register_operand" "+r")) + (set (match_dup 1) + (match_dup 0))] + "TARGET_64BIT" + "xchg{q}\\t%1, %0" + [(set_attr "type" "imov") + (set_attr "pent_pair" "np") + (set_attr "athlon_decode" "vector") + (set_attr "mode" "DI") + (set_attr "modrm" "0") + (set_attr "ppro_uops" "few")]) + (define_expand "movsf" [(set (match_operand:SF 0 "nonimmediate_operand" "") @@ -2197,7 +2566,7 @@ (define_insn "*pushsf" [(set (match_operand:SF 0 "push_operand" "=<,<,<") (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))] - "" + "!TARGET_64BIT" "* { switch (which_alternative) @@ -2224,6 +2593,37 @@ [(set_attr "type" "multi,push,multi") (set_attr "mode" "SF,SI,SF")]) +(define_insn "*pushsf_rex64" + [(set (match_operand:SF 0 "push_operand" "=X,X,X") + (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))] + "TARGET_64BIT" + "* +{ + switch (which_alternative) + { + case 0: + /* %%% We loose REG_DEAD notes for controling pops if we split late. */ + operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx); + operands[2] = stack_pointer_rtx; + operands[3] = GEN_INT (8); + if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) + return \"sub{q}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; + else + return \"sub{q}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; + + case 1: + return \"push{q}\\t%q1\"; + + case 2: + return \"#\"; + + default: + abort (); + } +}" + [(set_attr "type" "multi,push,multi") + (set_attr "mode" "SF,DI,SF")]) + (define_split [(set (match_operand:SF 0 "push_operand" "") (match_operand:SF 1 "memory_operand" ""))] @@ -2240,10 +2640,17 @@ (define_split [(set (match_operand:SF 0 "push_operand" "") (match_operand:SF 1 "register_operand" ""))] - "ANY_FP_REGNO_P (REGNO (operands[1]))" + "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))" [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4))) (set (mem:SF (reg:SI 7)) (match_dup 1))]) +(define_split + [(set (match_operand:SF 0 "push_operand" "") + (match_operand:SF 1 "register_operand" ""))] + "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))" + [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8))) + (set (mem:SF (reg:DI 7)) (match_dup 1))]) + (define_insn "*movsf_1" [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m") (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))] @@ -2331,7 +2738,7 @@ (define_insn "*pushdf_nointeger" [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))] - "!TARGET_INTEGER_DFMODE_MOVES" + "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" "* { switch (which_alternative) @@ -2361,7 +2768,7 @@ (define_insn "*pushdf_integer" [(set (match_operand:DF 0 "push_operand" "=<,<,<") (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))] - "TARGET_INTEGER_DFMODE_MOVES" + "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" "* { switch (which_alternative) @@ -2371,10 +2778,17 @@ operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx); operands[2] = stack_pointer_rtx; operands[3] = GEN_INT (8); - if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) - return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; + if (TARGET_64BIT) + if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) + return \"sub{q}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; + else + return \"sub{q}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; else - return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; + if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) + return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; + else + return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; + case 1: case 2: @@ -2391,11 +2805,19 @@ (define_split [(set (match_operand:DF 0 "push_operand" "") (match_operand:DF 1 "register_operand" ""))] - "reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))" + "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))" [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8))) (set (mem:DF (reg:SI 7)) (match_dup 1))] "") +(define_split + [(set (match_operand:DF 0 "push_operand" "") + (match_operand:DF 1 "register_operand" ""))] + "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))" + [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8))) + (set (mem:DF (reg:DI 7)) (match_dup 1))] + "") + (define_split [(set (match_operand:DF 0 "push_operand" "") (match_operand:DF 1 "general_operand" ""))] @@ -2673,10 +3095,16 @@ operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx); operands[2] = stack_pointer_rtx; operands[3] = GEN_INT (16); - if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) - return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; + if (TARGET_64BIT) + if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) + return \"sub{q}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; + else + return \"sub{q}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; else - return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; + if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) + return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\"; + else + return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\"; case 1: return \"#\"; @@ -2702,17 +3130,24 @@ (define_split [(set (match_operand:XF 0 "push_operand" "") (match_operand:XF 1 "register_operand" ""))] - "ANY_FP_REGNO_P (REGNO (operands[1]))" + "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))" [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12))) (set (mem:XF (reg:SI 7)) (match_dup 1))]) (define_split [(set (match_operand:TF 0 "push_operand" "") (match_operand:TF 1 "register_operand" ""))] - "ANY_FP_REGNO_P (REGNO (operands[1]))" + "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))" [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16))) (set (mem:TF (reg:SI 7)) (match_dup 1))]) +(define_split + [(set (match_operand:TF 0 "push_operand" "") + (match_operand:TF 1 "register_operand" ""))] + "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))" + [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16))) + (set (mem:TF (reg:DI 7)) (match_dup 1))]) + ;; Do not use integer registers when optimizing for size (define_insn "*movxf_nointeger" [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") -- 2.30.2