aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2010-06-22 15:36:15 +0200
committerUros Bizjak <uros@gcc.gnu.org>2010-06-22 15:36:15 +0200
commita8ecfc9f2c532fdf26326b1f65fef3323fc2ad47 (patch)
tree2ec5e581162ebc1c47b7164e006b8207380aab87 /gcc
parentb81a5940b446f84086ec6dbf536c516ee117b250 (diff)
downloadgcc-a8ecfc9f2c532fdf26326b1f65fef3323fc2ad47.zip
gcc-a8ecfc9f2c532fdf26326b1f65fef3323fc2ad47.tar.gz
gcc-a8ecfc9f2c532fdf26326b1f65fef3323fc2ad47.tar.bz2
i386.md (SWI1248x): New mode iterator.
* config/i386/i386.md (SWI1248x): New mode iterator. (SWI48x): Ditto. (SWI12): Ditto. (SWI24): Ditto. (mov<mode>): Macroize expander from mov{qi,hi,si,di} using SWI1248x mode iterator. (*push<mode>2_rex64): Macroize insn from *push{qi,hi,si}_rex64 using SWI124 mode iterator. (*push<mode>2): Macroize insn from *push{qi,hi} using SWI12 mode iterator. (*push<mode>2_prologue): Macroize insn from *pushsi2_prologue and *pushdi2_prologue_rex64 using P mode iterator. (*mov<mode>_xor): Macroize insn from *movsi_xor and *movdi_xor_rex64 using SWI48 mode iterator. (*mov<mode>_or): Ditto from *movsi_or and *movdi_or_rex64. (*movabs<mode>_1): Macroize insn from *movabs{qi,hi,si,di}_1_rex64 using SWI1248x mode iterator. (*movabs<mode>_2): Ditto from *movabs{qi,hi,si,di}_1_rex64. (*swap<mode>): Macroize insn from *swapsi and *swapdi_rex64 using SWI48 mode iterator. (*swap<mode>_1): Macroize insn from *swap{qi,hi}_1 using SWI12 mode iterator. (*swap<mode>_2): Ditto from *swap{qi,hi}_2. (movstrict<mode>): Macroize expander from movstrict{qi,hi} using SWI12 mode iterator. (*movstrict<mode>_1): Macroize insn from *movstrict{qi,hi}_1 using SWI12 mode iterator. (*movstrict<mode>_xor): Ditto from *movstrict{qi,hi}_xor. (*mov<mode>_extv_1): Macroize insn from *mov{hi,si}_extv_1 using SWI24 mode iterator. (*mov<mode>_extzv_1): Macroize insn from *mov{si,di}_extzv_1 using SWI48 mode iterator. (mov<mode>_insn_1): New expander. (*mov<mode>_insv_1_rex64): Macroize insn from *mov{si,di}_insv_1_rex64 using SWI48x mode iterator. (*movoi_internal_avx): Rename from *movoi_internal. (*movti_internal_rex64): Rename from *movti_rex64. (*movti_internal_sse): Rename from *movti_sse. (*movdi_internal_rex64): Rename from *movdi_1_rex64. (*movdi_internal): Rename from *movdi_2. (*movsi_internal): Rename from *movsi_1. (*movhi_internal): Rename from *movhi_1. (*movqi_internal): Rename from *movqi_1. (insv): Update the call to gen_movsi_insv_1 for rename. * config/i386/i386.c (promote_duplicated_reg): Ditto. From-SVN: r161185
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog60
-rw-r--r--gcc/config/i386/i386.c2
-rw-r--r--gcc/config/i386/i386.md1493
3 files changed, 676 insertions, 879 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e1e0769..ca0ebf5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,54 @@
+2010-06-22 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (SWI1248x): New mode iterator.
+ (SWI48x): Ditto.
+ (SWI12): Ditto.
+ (SWI24): Ditto.
+
+ (mov<mode>): Macroize expander from mov{qi,hi,si,di} using
+ SWI1248x mode iterator.
+ (*push<mode>2_rex64): Macroize insn from *push{qi,hi,si}_rex64
+ using SWI124 mode iterator.
+ (*push<mode>2): Macroize insn from *push{qi,hi} using SWI12
+ mode iterator.
+ (*push<mode>2_prologue): Macroize insn from *pushsi2_prologue and
+ *pushdi2_prologue_rex64 using P mode iterator.
+ (*mov<mode>_xor): Macroize insn from *movsi_xor and *movdi_xor_rex64
+ using SWI48 mode iterator.
+ (*mov<mode>_or): Ditto from *movsi_or and *movdi_or_rex64.
+ (*movabs<mode>_1): Macroize insn from *movabs{qi,hi,si,di}_1_rex64
+ using SWI1248x mode iterator.
+ (*movabs<mode>_2): Ditto from *movabs{qi,hi,si,di}_1_rex64.
+ (*swap<mode>): Macroize insn from *swapsi and *swapdi_rex64 using
+ SWI48 mode iterator.
+ (*swap<mode>_1): Macroize insn from *swap{qi,hi}_1 using SWI12 mode
+ iterator.
+ (*swap<mode>_2): Ditto from *swap{qi,hi}_2.
+ (movstrict<mode>): Macroize expander from movstrict{qi,hi} using
+ SWI12 mode iterator.
+ (*movstrict<mode>_1): Macroize insn from *movstrict{qi,hi}_1 using
+ SWI12 mode iterator.
+ (*movstrict<mode>_xor): Ditto from *movstrict{qi,hi}_xor.
+ (*mov<mode>_extv_1): Macroize insn from *mov{hi,si}_extv_1 using
+ SWI24 mode iterator.
+ (*mov<mode>_extzv_1): Macroize insn from *mov{si,di}_extzv_1 using
+ SWI48 mode iterator.
+ (mov<mode>_insn_1): New expander.
+ (*mov<mode>_insv_1_rex64): Macroize insn from *mov{si,di}_insv_1_rex64
+ using SWI48x mode iterator.
+
+ (*movoi_internal_avx): Rename from *movoi_internal.
+ (*movti_internal_rex64): Rename from *movti_rex64.
+ (*movti_internal_sse): Rename from *movti_sse.
+ (*movdi_internal_rex64): Rename from *movdi_1_rex64.
+ (*movdi_internal): Rename from *movdi_2.
+ (*movsi_internal): Rename from *movsi_1.
+ (*movhi_internal): Rename from *movhi_1.
+ (*movqi_internal): Rename from *movqi_1.
+
+ (insv): Update the call to gen_movsi_insv_1 for rename.
+ * config/i386/i386.c (promote_duplicated_reg): Ditto.
+
2010-06-22 Jan Hubicka <jh@suse.cz>
* passes.c (execute_function_todo): Move call of statistics_fini_pass
@@ -231,8 +282,7 @@
2010-06-19 Philip Herron <herron.philip@googlemail.com>
- * c-decl.c (c_write_global_declarations): Don't check
- flag_syntax_only.
+ * c-decl.c (c_write_global_declarations): Don't check flag_syntax_only.
2010-06-18 H.J. Lu <hongjiu.lu@intel.com>
@@ -269,8 +319,7 @@
* function.h (types_used_by_cur_var_decl): Change type to a VEC.
* function.c (types_used_by_cur_var_decl): Likewise.
- (used_types_insert): Adjust for new type of
- types_used_by_cur_var_decl.
+ (used_types_insert): Adjust for new type of types_used_by_cur_var_decl.
2010-06-18 Nathan Froyd <froydnj@codesourcery.com>
@@ -512,8 +561,7 @@
(PRINT_OPERAND_PUNCT_VALID_P): Delete.
(PRINT_OPERAND_ADDRESS, ARM_PRINT_OPERAND_ADDRESS):
(THUMB_PRINT_OPERAND_ADDRESS): Delete and move code to...
- * config/arm/arm.c (arm_print_operand_address): ...here. New
- function.
+ * config/arm/arm.c (arm_print_operand_address): ...here. New function.
(arm_print_operand): Make static.
(arm_print_operand_punct_valid_p): New function.
(TARGET_PRINT_OPERAND, TARGET_PRINT_OPERAND_ADDRESS):
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 7d97a6a..76be5d5 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -18838,7 +18838,7 @@ promote_duplicated_reg (enum machine_mode mode, rtx val)
if (mode == SImode)
emit_insn (gen_movsi_insv_1 (reg, reg));
else
- emit_insn (gen_movdi_insv_1_rex64 (reg, reg));
+ emit_insn (gen_movdi_insv_1 (reg, reg));
else
{
tmp = expand_simple_binop (mode, ASHIFT, reg, GEN_INT (8),
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 4894669..e934696 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -765,12 +765,24 @@
(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
(div "i") (udiv "")])
-;; All single word integer modes.
+;; 64bit single word integer modes.
+(define_mode_iterator SWI1248x [QI HI SI DI])
+
+;; 64bit single word integer modes without QImode and HImode.
+(define_mode_iterator SWI48x [SI DI])
+
+;; Single word integer modes.
(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
+;; Single word integer modes without SImode and DImode.
+(define_mode_iterator SWI12 [QI HI])
+
;; Single word integer modes without DImode.
(define_mode_iterator SWI124 [QI HI SI])
+;; Single word integer modes without QImode and DImode.
+(define_mode_iterator SWI24 [HI SI])
+
;; Single word integer modes without QImode.
(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
@@ -1585,13 +1597,47 @@
;; Move instructions.
-;; General case of fullword move.
+(define_expand "movoi"
+ [(set (match_operand:OI 0 "nonimmediate_operand" "")
+ (match_operand:OI 1 "general_operand" ""))]
+ "TARGET_AVX"
+ "ix86_expand_move (OImode, operands); DONE;")
-(define_expand "movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
+(define_expand "movti"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "")
+ (match_operand:TI 1 "nonimmediate_operand" ""))]
+ "TARGET_64BIT || TARGET_SSE"
+{
+ if (TARGET_64BIT)
+ ix86_expand_move (TImode, operands);
+ else if (push_operand (operands[0], TImode))
+ ix86_expand_push (TImode, operands[1]);
+ else
+ ix86_expand_vector_move (TImode, operands);
+ DONE;
+})
+
+;; This expands to what emit_move_complex would generate if we didn't
+;; have a movti pattern. Having this avoids problems with reload on
+;; 32-bit targets when SSE is present, but doesn't seem to be harmful
+;; to have around all the time.
+(define_expand "movcdi"
+ [(set (match_operand:CDI 0 "nonimmediate_operand" "")
+ (match_operand:CDI 1 "general_operand" ""))]
""
- "ix86_expand_move (SImode, operands); DONE;")
+{
+ if (push_operand (operands[0], CDImode))
+ emit_move_complex_push (CDImode, operands[0], operands[1]);
+ else
+ emit_move_complex_parts (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "mov<mode>"
+ [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
+ (match_operand:SWI1248x 1 "general_operand" ""))]
+ ""
+ "ix86_expand_move (<MODE>mode, operands); DONE;")
;; Push/pop instructions. They are separate since autoinc/dec is not a
;; general_operand.
@@ -1602,6 +1648,79 @@
;; targets without our curiosities, and it is just as easy to represent
;; this differently.
+(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 through 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.
+;; "&& 1" is needed to keep it from matching the previous pattern.
+(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 && ((optimize > 0 && flag_peephole2)
+ ? epilogue_completed : reload_completed)
+ && !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"
+ [(set (match_operand:DI 0 "push_operand" "=<")
+ (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
+ "!TARGET_64BIT"
+ "#")
+
+(define_split
+ [(set (match_operand:DI 0 "push_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ "!TARGET_64BIT && reload_completed
+ && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
+ [(const_int 0)]
+ "ix86_split_long_move (operands); DONE;")
+
(define_insn "*pushsi2"
[(set (match_operand:SI 0 "push_operand" "=<")
(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
@@ -1610,70 +1729,402 @@
[(set_attr "type" "push")
(set_attr "mode" "SI")])
+;; emit_push_insn when it calls move_by_pieces requires an insn to
+;; "push a byte/word". But actually we use pushl, which has the effect
+;; of rounding the amount pushed up to a word.
+
;; 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"))]
+(define_insn "*push<mode>2_rex64"
+ [(set (match_operand:SWI124 0 "push_operand" "=X")
+ (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
"TARGET_64BIT"
"push{q}\t%q1"
[(set_attr "type" "push")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "DI")])
-(define_insn "*pushsi2_prologue"
- [(set (match_operand:SI 0 "push_operand" "=<")
- (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
- (clobber (mem:BLK (scratch)))]
+(define_insn "*push<mode>2"
+ [(set (match_operand:SWI12 0 "push_operand" "=X")
+ (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
"!TARGET_64BIT"
- "push{l}\t%1"
+ "push{l}\t%k1"
[(set_attr "type" "push")
(set_attr "mode" "SI")])
-(define_insn "*popsi1_epilogue"
+(define_insn "*push<mode>2_prologue"
+ [(set (match_operand:P 0 "push_operand" "=<")
+ (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "push{<imodesuffix>}\t%1"
+ [(set_attr "type" "push")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "popdi1"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
+ (mem:DI (reg:DI SP_REG)))
+ (set (reg:DI SP_REG)
+ (plus:DI (reg:DI SP_REG) (const_int 8)))]
+ "TARGET_64BIT"
+ "pop{q}\t%0"
+ [(set_attr "type" "pop")
+ (set_attr "mode" "DI")])
+
+(define_insn "popsi1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
(mem:SI (reg:SI SP_REG)))
(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int 4)))
- (clobber (mem:BLK (scratch)))]
+ (plus:SI (reg:SI SP_REG) (const_int 4)))]
"!TARGET_64BIT"
"pop{l}\t%0"
[(set_attr "type" "pop")
(set_attr "mode" "SI")])
-(define_insn "popsi1"
+(define_insn "*popdi1_epilogue"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
+ (mem:DI (reg:DI SP_REG)))
+ (set (reg:DI SP_REG)
+ (plus:DI (reg:DI SP_REG) (const_int 8)))
+ (clobber (mem:BLK (scratch)))]
+ "TARGET_64BIT"
+ "pop{q}\t%0"
+ [(set_attr "type" "pop")
+ (set_attr "mode" "DI")])
+
+(define_insn "*popsi1_epilogue"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
(mem:SI (reg:SI SP_REG)))
(set (reg:SI SP_REG)
- (plus:SI (reg:SI SP_REG) (const_int 4)))]
+ (plus:SI (reg:SI SP_REG) (const_int 4)))
+ (clobber (mem:BLK (scratch)))]
"!TARGET_64BIT"
"pop{l}\t%0"
[(set_attr "type" "pop")
(set_attr "mode" "SI")])
-(define_insn "*movsi_xor"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "const0_operand" ""))
+(define_insn "*mov<mode>_xor"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (match_operand:SWI48 1 "const0_operand" ""))
(clobber (reg:CC FLAGS_REG))]
"reload_completed"
- "xor{l}\t%0, %0"
+ "xor{l}\t%k0, %k0"
[(set_attr "type" "alu1")
(set_attr "mode" "SI")
(set_attr "length_immediate" "0")])
-(define_insn "*movsi_or"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "immediate_operand" "i"))
+(define_insn "*mov<mode>_or"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (match_operand:SWI48 1 "const_int_operand" ""))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
&& operands[1] == constm1_rtx"
-{
- operands[1] = constm1_rtx;
- return "or{l}\t{%1, %0|%0, %1}";
-}
+ "or{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "alu1")
- (set_attr "mode" "SI")
+ (set_attr "mode" "<MODE>")
(set_attr "length_immediate" "1")])
-(define_insn "*movsi_1"
+(define_insn "*movoi_internal_avx"
+ [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
+ "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "vxorps\t%0, %0, %0";
+ case 1:
+ case 2:
+ if (misaligned_operand (operands[0], OImode)
+ || misaligned_operand (operands[1], OImode))
+ return "vmovdqu\t{%1, %0|%0, %1}";
+ else
+ return "vmovdqa\t{%1, %0|%0, %1}";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "sselog1,ssemov,ssemov")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "OI")])
+
+(define_insn "*movti_internal_rex64"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
+ (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
+ "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return "#";
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "%vxorps\t%0, %d0";
+ else
+ return "%vpxor\t%0, %d0";
+ case 3:
+ case 4:
+ /* TDmode values are passed as TImode on the stack. Moving them
+ to stack may result in unaligned memory access. */
+ if (misaligned_operand (operands[0], TImode)
+ || misaligned_operand (operands[1], TImode))
+ {
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "%vmovups\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqu\t{%1, %0|%0, %1}";
+ }
+ else
+ {
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "%vmovaps\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqa\t{%1, %0|%0, %1}";
+ }
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
+ (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "2,3")
+ (if_then_else
+ (ne (symbol_ref "optimize_function_for_size_p (cfun)")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "4")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_function_for_size_p (cfun)")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "DI")))])
+
+(define_split
+ [(set (match_operand:TI 0 "nonimmediate_operand" "")
+ (match_operand:TI 1 "general_operand" ""))]
+ "reload_completed
+ && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
+ [(const_int 0)]
+ "ix86_split_long_move (operands); DONE;")
+
+(define_insn "*movti_internal_sse"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
+ (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
+ "TARGET_SSE && !TARGET_64BIT
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "%vxorps\t%0, %d0";
+ else
+ return "%vpxor\t%0, %d0";
+ case 1:
+ case 2:
+ /* TDmode values are passed as TImode on the stack. Moving them
+ to stack may result in unaligned memory access. */
+ if (misaligned_operand (operands[0], TImode)
+ || misaligned_operand (operands[1], TImode))
+ {
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "%vmovups\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqu\t{%1, %0|%0, %1}";
+ }
+ else
+ {
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "%vmovaps\t{%1, %0|%0, %1}";
+ else
+ return "%vmovdqa\t{%1, %0|%0, %1}";
+ }
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "sselog1,ssemov,ssemov")
+ (set_attr "prefix" "maybe_vex")
+ (set (attr "mode")
+ (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
+ (ne (symbol_ref "optimize_function_for_size_p (cfun)")
+ (const_int 0)))
+ (const_string "V4SF")
+ (and (eq_attr "alternative" "2")
+ (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0)))
+ (const_string "V4SF")]
+ (const_string "TI")))])
+
+(define_insn "*movdi_internal_rex64"
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
+ (match_operand:DI 1 "general_operand"
+ "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
+ "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+{
+ switch (get_attr_type (insn))
+ {
+ case TYPE_SSECVT:
+ if (SSE_REG_P (operands[0]))
+ return "movq2dq\t{%1, %0|%0, %1}";
+ else
+ return "movdq2q\t{%1, %0|%0, %1}";
+
+ case TYPE_SSEMOV:
+ if (TARGET_AVX)
+ {
+ if (get_attr_mode (insn) == MODE_TI)
+ return "vmovdqa\t{%1, %0|%0, %1}";
+ else
+ return "vmovq\t{%1, %0|%0, %1}";
+ }
+
+ if (get_attr_mode (insn) == MODE_TI)
+ return "movdqa\t{%1, %0|%0, %1}";
+ /* FALLTHRU */
+
+ case TYPE_MMXMOV:
+ /* Moves from and into integer register is done using movd
+ opcode with REX prefix. */
+ if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
+ return "movd\t{%1, %0|%0, %1}";
+ return "movq\t{%1, %0|%0, %1}";
+
+ case TYPE_SSELOG1:
+ return "%vpxor\t%0, %d0";
+
+ case TYPE_MMX:
+ return "pxor\t%0, %0";
+
+ case TYPE_MULTI:
+ return "#";
+
+ case TYPE_LEA:
+ return "lea{q}\t{%a1, %0|%0, %a1}";
+
+ default:
+ gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
+ 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")
+ (const_string "mmx")
+ (eq_attr "alternative" "6,7,8,9,10")
+ (const_string "mmxmov")
+ (eq_attr "alternative" "11")
+ (const_string "sselog1")
+ (eq_attr "alternative" "12,13,14,15,16")
+ (const_string "ssemov")
+ (eq_attr "alternative" "17,18")
+ (const_string "ssecvt")
+ (eq_attr "alternative" "4")
+ (const_string "multi")
+ (match_operand:DI 1 "pic_32bit_operand" "")
+ (const_string "lea")
+ ]
+ (const_string "imov")))
+ (set (attr "modrm")
+ (if_then_else
+ (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+ (const_string "0")
+ (const_string "*")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+ (const_string "8")
+ (const_string "*")))
+ (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
+ (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
+ (set (attr "prefix")
+ (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
+ (const_string "maybe_vex")
+ (const_string "orig")))
+ (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
+
+;; Convert impossible stores of immediate to existing instructions.
+;; First try to get scratch register and go through 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.
+;; "&& 1" is needed to keep it from matching the previous pattern.
+(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[0], 2, &operands[2], &operands[4]);")
+
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (match_operand:DI 1 "immediate_operand" ""))]
+ "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
+ ? epilogue_completed : reload_completed)
+ && !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[0], 2, &operands[2], &operands[4]);")
+
+(define_insn "*movdi_internal"
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
+ (match_operand:DI 1 "general_operand"
+ "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
+ "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "@
+ #
+ #
+ pxor\t%0, %0
+ movq\t{%1, %0|%0, %1}
+ movq\t{%1, %0|%0, %1}
+ %vpxor\t%0, %d0
+ %vmovq\t{%1, %0|%0, %1}
+ %vmovdqa\t{%1, %0|%0, %1}
+ %vmovq\t{%1, %0|%0, %1}
+ xorps\t%0, %0
+ movlps\t{%1, %0|%0, %1}
+ movaps\t{%1, %0|%0, %1}
+ movlps\t{%1, %0|%0, %1}"
+ [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
+ (set (attr "prefix")
+ (if_then_else (eq_attr "alternative" "5,6,7,8")
+ (const_string "vex")
+ (const_string "orig")))
+ (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
+
+(define_split
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ "!TARGET_64BIT && reload_completed
+ && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
+ && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
+ [(const_int 0)]
+ "ix86_split_long_move (operands); DONE;")
+
+(define_insn "*movsi_internal"
[(set (match_operand:SI 0 "nonimmediate_operand"
"=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
(match_operand:SI 1 "general_operand"
@@ -1753,74 +2204,7 @@
]
(const_string "SI")))])
-;; Stores and loads of ax to arbitrary 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"))
- (match_operand:SI 1 "nonmemory_operand" "a,er"))]
- "TARGET_64BIT && ix86_check_movabs (insn, 0)"
- "@
- movabs{l}\t{%1, %P0|%P0, %1}
- mov{l}\t{%1, %a0|%a0, %1}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0,*")
- (set_attr "length_address" "8,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 && ix86_check_movabs (insn, 1)"
- "@
- 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"))
- (set (match_dup 1)
- (match_dup 0))]
- ""
- "xchg{l}\t%1, %0"
- [(set_attr "type" "imov")
- (set_attr "mode" "SI")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "double")])
-
-(define_expand "movhi"
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
- "ix86_expand_move (HImode, operands); DONE;")
-
-(define_insn "*pushhi2"
- [(set (match_operand:HI 0 "push_operand" "=X")
- (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
- "!TARGET_64BIT"
- "push{l}\t%k1"
- [(set_attr "type" "push")
- (set_attr "mode" "SI")])
-
-;; For 64BIT abi we always round up to 8 bytes.
-(define_insn "*pushhi2_rex64"
- [(set (match_operand:HI 0 "push_operand" "=X")
- (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
- "TARGET_64BIT"
- "push{q}\t%q1"
- [(set_attr "type" "push")
- (set_attr "mode" "DI")])
-
-(define_insn "*movhi_1"
+(define_insn "*movhi_internal"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
@@ -1839,7 +2223,8 @@
}
}
[(set (attr "type")
- (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
+ (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
+ (const_int 0))
(const_string "imov")
(and (eq_attr "alternative" "0")
(ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
@@ -1871,121 +2256,6 @@
]
(const_string "HI")))])
-;; Stores and loads of ax to arbitrary 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"))
- (match_operand:HI 1 "nonmemory_operand" "a,er"))]
- "TARGET_64BIT && ix86_check_movabs (insn, 0)"
- "@
- movabs{w}\t{%1, %P0|%P0, %1}
- mov{w}\t{%1, %a0|%a0, %1}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0,*")
- (set_attr "length_address" "8,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 && ix86_check_movabs (insn, 1)"
- "@
- 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"))
- (set (match_dup 1)
- (match_dup 0))]
- "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
- "xchg{l}\t%k1, %k0"
- [(set_attr "type" "imov")
- (set_attr "mode" "SI")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "double")])
-
-;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
-(define_insn "*swaphi_2"
- [(set (match_operand:HI 0 "register_operand" "+r")
- (match_operand:HI 1 "register_operand" "+r"))
- (set (match_dup 1)
- (match_dup 0))]
- "TARGET_PARTIAL_REG_STALL"
- "xchg{w}\t%1, %0"
- [(set_attr "type" "imov")
- (set_attr "mode" "HI")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")])
-
-(define_expand "movstricthi"
- [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
- (match_operand:HI 1 "general_operand" ""))]
- ""
-{
- if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
- FAIL;
- /* Don't generate memory->memory moves, go through a register */
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[1] = force_reg (HImode, operands[1]);
-})
-
-(define_insn "*movstricthi_1"
- [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
- (match_operand:HI 1 "general_operand" "rn,m"))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "mov{w}\t{%1, %0|%0, %1}"
- [(set_attr "type" "imov")
- (set_attr "mode" "HI")])
-
-(define_insn "*movstricthi_xor"
- [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
- (match_operand:HI 1 "const0_operand" ""))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed"
- "xor{w}\t%0, %0"
- [(set_attr "type" "alu1")
- (set_attr "mode" "HI")
- (set_attr "length_immediate" "0")])
-
-(define_expand "movqi"
- [(set (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
- ""
- "ix86_expand_move (QImode, operands); DONE;")
-
-;; emit_push_insn when it calls move_by_pieces requires an insn to
-;; "push a byte". But actually we use pushl, which has the effect
-;; of rounding the amount pushed up to a word.
-
-(define_insn "*pushqi2"
- [(set (match_operand:QI 0 "push_operand" "=X")
- (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
- "!TARGET_64BIT"
- "push{l}\t%k1"
- [(set_attr "type" "push")
- (set_attr "mode" "SI")])
-
-;; For 64BIT abi we always round up to 8 bytes.
-(define_insn "*pushqi2_rex64"
- [(set (match_operand:QI 0 "push_operand" "=X")
- (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
- "TARGET_64BIT"
- "push{q}\t%q1"
- [(set_attr "type" "push")
- (set_attr "mode" "DI")])
-
;; Situation is quite tricky about when to choose full sized (SImode) move
;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
;; partial register dependency machines (such as AMD Athlon), where QImode
@@ -1996,7 +2266,7 @@
;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
;; register stall machines with, where we use QImode instructions, since
;; partial register stall can be caused there. Then we use movzx.
-(define_insn "*movqi_1"
+(define_insn "*movqi_internal"
[(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
(match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
@@ -2017,7 +2287,8 @@
(cond [(and (eq_attr "alternative" "5")
(not (match_operand:QI 1 "aligned_operand" "")))
(const_string "imovx")
- (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
+ (ne (symbol_ref "optimize_function_for_size_p (cfun)")
+ (const_int 0))
(const_string "imov")
(and (eq_attr "alternative" "3")
(ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
@@ -2046,7 +2317,7 @@
(const_int 0))
(and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
(const_int 0))
- (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
+ (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
(const_int 0))))))
(const_string "SI")
;; Avoid partial register stalls when not using QImode arithmetic
@@ -2060,9 +2331,53 @@
]
(const_string "QI")))])
-(define_insn "*swapqi_1"
- [(set (match_operand:QI 0 "register_operand" "+r")
- (match_operand:QI 1 "register_operand" "+r"))
+;; Stores and loads of ax to arbitrary constant address.
+;; We fake an second form of instruction to force reload to load address
+;; into register when rax is not available
+(define_insn "*movabs<mode>_1"
+ [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
+ (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
+ "TARGET_64BIT && ix86_check_movabs (insn, 0)"
+ "@
+ movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
+ mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
+ [(set_attr "type" "imov")
+ (set_attr "modrm" "0,*")
+ (set_attr "length_address" "8,0")
+ (set_attr "length_immediate" "0,*")
+ (set_attr "memory" "store")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*movabs<mode>_2"
+ [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
+ (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
+ "TARGET_64BIT && ix86_check_movabs (insn, 1)"
+ "@
+ movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
+ mov{<imodesuffix>}\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" "<MODE>")])
+
+(define_insn "*swap<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "+r")
+ (match_operand:SWI48 1 "register_operand" "+r"))
+ (set (match_dup 1)
+ (match_dup 0))]
+ ""
+ "xchg{<imodesuffix>}\t%1, %0"
+ [(set_attr "type" "imov")
+ (set_attr "mode" "<MODE>")
+ (set_attr "pent_pair" "np")
+ (set_attr "athlon_decode" "vector")
+ (set_attr "amdfam10_decode" "double")])
+
+(define_insn "*swap<mode>_1"
+ [(set (match_operand:SWI12 0 "register_operand" "+r")
+ (match_operand:SWI12 1 "register_operand" "+r"))
(set (match_dup 1)
(match_dup 0))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
@@ -2071,78 +2386,70 @@
(set_attr "mode" "SI")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "vector")])
+ (set_attr "amdfam10_decode" "double")])
-;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
-(define_insn "*swapqi_2"
- [(set (match_operand:QI 0 "register_operand" "+q")
- (match_operand:QI 1 "register_operand" "+q"))
+;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
+;; is disabled for AMDFAM10
+(define_insn "*swap<mode>_2"
+ [(set (match_operand:SWI12 0 "register_operand" "+<r>")
+ (match_operand:SWI12 1 "register_operand" "+<r>"))
(set (match_dup 1)
(match_dup 0))]
"TARGET_PARTIAL_REG_STALL"
- "xchg{b}\t%1, %0"
+ "xchg{<imodesuffix>}\t%1, %0"
[(set_attr "type" "imov")
- (set_attr "mode" "QI")
+ (set_attr "mode" "<MODE>")
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")])
-(define_expand "movstrictqi"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
- (match_operand:QI 1 "general_operand" ""))]
+(define_expand "movstrict<mode>"
+ [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
+ (match_operand:SWI12 1 "general_operand" ""))]
""
{
if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
FAIL;
- /* Don't generate memory->memory moves, go through a register. */
+ /* Don't generate memory->memory moves, go through a register */
if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[1] = force_reg (QImode, operands[1]);
+ operands[1] = force_reg (<MODE>mode, operands[1]);
})
-(define_insn "*movstrictqi_1"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (match_operand:QI 1 "general_operand" "*qn,m"))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+(define_insn "*movstrict<mode>_1"
+ [(set (strict_low_part
+ (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
+ (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
+ "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "mov{b}\t{%1, %0|%0, %1}"
+ "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "imov")
- (set_attr "mode" "QI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn "*movstrictqi_xor"
- [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
- (match_operand:QI 1 "const0_operand" ""))
+(define_insn "*movstrict<mode>_xor"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (match_operand:SWI12 1 "const0_operand" ""))
(clobber (reg:CC FLAGS_REG))]
"reload_completed"
- "xor{b}\t%0, %0"
+ "xor{<imodesuffix>}\t%0, %0"
[(set_attr "type" "alu1")
- (set_attr "mode" "QI")
+ (set_attr "mode" "<MODE>")
(set_attr "length_immediate" "0")])
-(define_insn "*movsi_extv_1"
- [(set (match_operand:SI 0 "register_operand" "=R")
- (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)))]
- ""
- "movs{bl|x}\t{%h1, %0|%0, %h1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "*movhi_extv_1"
- [(set (match_operand:HI 0 "register_operand" "=R")
- (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)))]
+(define_insn "*mov<mode>_extv_1"
+ [(set (match_operand:SWI24 0 "register_operand" "=R")
+ (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
+ (const_int 8)
+ (const_int 8)))]
""
"movs{bl|x}\t{%h1, %k0|%k0, %h1}"
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
-(define_insn "*movqi_extv_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
+(define_insn "*movqi_extv_1_rex64"
+ [(set (match_operand:QI 0 "register_operand" "=Q,?R")
(sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
(const_int 8)
(const_int 8)))]
- "!TARGET_64BIT"
+ "TARGET_64BIT"
{
switch (get_attr_type (insn))
{
@@ -2164,12 +2471,12 @@
(const_string "SI")
(const_string "QI")))])
-(define_insn "*movqi_extv_1_rex64"
- [(set (match_operand:QI 0 "register_operand" "=Q,?R")
+(define_insn "*movqi_extv_1"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
(sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
(const_int 8)
(const_int 8)))]
- "TARGET_64BIT"
+ "!TARGET_64BIT"
{
switch (get_attr_type (insn))
{
@@ -2191,63 +2498,23 @@
(const_string "SI")
(const_string "QI")))])
-;; Stores and loads of ax to arbitrary 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"))
- (match_operand:QI 1 "nonmemory_operand" "a,er"))]
- "TARGET_64BIT && ix86_check_movabs (insn, 0)"
- "@
- movabs{b}\t{%1, %P0|%P0, %1}
- mov{b}\t{%1, %a0|%a0, %1}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0,*")
- (set_attr "length_address" "8,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 && ix86_check_movabs (insn, 1)"
- "@
- movabs{b}\t{%P1, %0|%0, %P1}
- mov{b}\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 "*movdi_extzv_1"
- [(set (match_operand:DI 0 "register_operand" "=R")
- (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)))]
- "TARGET_64BIT"
- "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
- [(set_attr "type" "imovx")
- (set_attr "mode" "SI")])
-
-(define_insn "*movsi_extzv_1"
- [(set (match_operand:SI 0 "register_operand" "=R")
- (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
- (const_int 8)
- (const_int 8)))]
+(define_insn "*mov<mode>_extzv_1"
+ [(set (match_operand:SWI48 0 "register_operand" "=R")
+ (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
+ (const_int 8)
+ (const_int 8)))]
""
- "movz{bl|x}\t{%h1, %0|%0, %h1}"
+ "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
-(define_insn "*movqi_extzv_2"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
- (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)) 0))]
- "!TARGET_64BIT"
+(define_insn "*movqi_extzv_2_rex64"
+ [(set (match_operand:QI 0 "register_operand" "=Q,?R")
+ (subreg:QI
+ (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
+ (const_int 8)
+ (const_int 8)) 0))]
+ "TARGET_64BIT"
{
switch (get_attr_type (insn))
{
@@ -2258,10 +2525,9 @@
}
}
[(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))))
+ (if_then_else (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")
@@ -2269,12 +2535,13 @@
(const_string "SI")
(const_string "QI")))])
-(define_insn "*movqi_extzv_2_rex64"
- [(set (match_operand:QI 0 "register_operand" "=Q,?R")
- (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
- (const_int 8)
- (const_int 8)) 0))]
- "TARGET_64BIT"
+(define_insn "*movqi_extzv_2"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
+ (subreg:QI
+ (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
+ (const_int 8)
+ (const_int 8)) 0))]
+ "!TARGET_64BIT"
{
switch (get_attr_type (insn))
{
@@ -2285,9 +2552,10 @@
}
}
[(set (attr "type")
- (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
- (ne (symbol_ref "TARGET_MOVX")
- (const_int 0)))
+ (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")
@@ -2295,32 +2563,30 @@
(const_string "SI")
(const_string "QI")))])
-(define_insn "movsi_insv_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
- (const_int 8)
- (const_int 8))
- (match_operand:SI 1 "general_operand" "Qmn"))]
- "!TARGET_64BIT"
- "mov{b}\t{%b1, %h0|%h0, %b1}"
- [(set_attr "type" "imov")
- (set_attr "mode" "QI")])
+(define_expand "mov<mode>_insv_1"
+ [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
+ (const_int 8)
+ (const_int 8))
+ (match_operand:SWI48 1 "nonmemory_operand" ""))]
+ ""
+ "")
-(define_insn "*movsi_insv_1_rex64"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
- (const_int 8)
- (const_int 8))
- (match_operand:SI 1 "nonmemory_operand" "Qn"))]
+(define_insn "*mov<mode>_insv_1_rex64"
+ [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
+ (const_int 8)
+ (const_int 8))
+ (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
"TARGET_64BIT"
"mov{b}\t{%b1, %h0|%h0, %b1}"
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
-(define_insn "movdi_insv_1_rex64"
- [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
+(define_insn "*movsi_insv_1"
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
- (match_operand:DI 1 "nonmemory_operand" "Qn"))]
- "TARGET_64BIT"
+ (match_operand:SI 1 "general_operand" "Qmn"))]
+ "!TARGET_64BIT"
"mov{b}\t{%b1, %h0|%h0, %b1}"
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
@@ -2335,525 +2601,8 @@
"mov{b}\t{%h1, %h0|%h0, %h1}"
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
-
-(define_expand "movdi"
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
- ""
- "ix86_expand_move (DImode, operands); DONE;")
-
-(define_insn "*pushdi"
- [(set (match_operand:DI 0 "push_operand" "=<")
- (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
- "!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 through 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.
-;; "&& 1" is needed to keep it from matching the previous pattern.
-(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 && ((optimize > 0 && flag_peephole2)
- ? epilogue_completed : reload_completed)
- && !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"))
- (clobber (mem:BLK (scratch)))]
- "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 SP_REG)))
- (set (reg:DI SP_REG)
- (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (mem:BLK (scratch)))]
- "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 SP_REG)))
- (set (reg:DI SP_REG)
- (plus:DI (reg:DI SP_REG) (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" ""))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_64BIT
- && reload_completed"
- "xor{l}\t%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 FLAGS_REG))]
- "TARGET_64BIT
- && reload_completed
- && operands[1] == constm1_rtx"
-{
- 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 ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
- (match_operand:DI 1 "general_operand"
- "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
- "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "@
- #
- #
- pxor\t%0, %0
- movq\t{%1, %0|%0, %1}
- movq\t{%1, %0|%0, %1}
- %vpxor\t%0, %d0
- %vmovq\t{%1, %0|%0, %1}
- %vmovdqa\t{%1, %0|%0, %1}
- %vmovq\t{%1, %0|%0, %1}
- xorps\t%0, %0
- movlps\t{%1, %0|%0, %1}
- movaps\t{%1, %0|%0, %1}
- movlps\t{%1, %0|%0, %1}"
- [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "5,6,7,8")
- (const_string "vex")
- (const_string "orig")))
- (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
-
-(define_split
- [(set (match_operand:DI 0 "push_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
- "!TARGET_64BIT && reload_completed
- && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-;; %%% This multiword shite has got to go.
-(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
- "!TARGET_64BIT && reload_completed
- && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
- && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-(define_insn "*movdi_1_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand"
- "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
- (match_operand:DI 1 "general_operand"
- "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (get_attr_type (insn))
- {
- case TYPE_SSECVT:
- if (SSE_REG_P (operands[0]))
- return "movq2dq\t{%1, %0|%0, %1}";
- else
- return "movdq2q\t{%1, %0|%0, %1}";
-
- case TYPE_SSEMOV:
- if (TARGET_AVX)
- {
- if (get_attr_mode (insn) == MODE_TI)
- return "vmovdqa\t{%1, %0|%0, %1}";
- else
- return "vmovq\t{%1, %0|%0, %1}";
- }
-
- if (get_attr_mode (insn) == MODE_TI)
- return "movdqa\t{%1, %0|%0, %1}";
- /* FALLTHRU */
-
- case TYPE_MMXMOV:
- /* Moves from and into integer register is done using movd
- opcode with REX prefix. */
- if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
- return "movd\t{%1, %0|%0, %1}";
- return "movq\t{%1, %0|%0, %1}";
-
- case TYPE_SSELOG1:
- return "%vpxor\t%0, %d0";
-
- case TYPE_MMX:
- return "pxor\t%0, %0";
-
- case TYPE_MULTI:
- return "#";
-
- case TYPE_LEA:
- return "lea{q}\t{%a1, %0|%0, %a1}";
-
- default:
- gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
- 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")
- (const_string "mmx")
- (eq_attr "alternative" "6,7,8,9,10")
- (const_string "mmxmov")
- (eq_attr "alternative" "11")
- (const_string "sselog1")
- (eq_attr "alternative" "12,13,14,15,16")
- (const_string "ssemov")
- (eq_attr "alternative" "17,18")
- (const_string "ssecvt")
- (eq_attr "alternative" "4")
- (const_string "multi")
- (match_operand:DI 1 "pic_32bit_operand" "")
- (const_string "lea")
- ]
- (const_string "imov")))
- (set (attr "modrm")
- (if_then_else
- (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
- (const_string "0")
- (const_string "*")))
- (set (attr "length_immediate")
- (if_then_else
- (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
- (const_string "8")
- (const_string "*")))
- (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
- (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
- (set (attr "prefix")
- (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
- (const_string "maybe_vex")
- (const_string "orig")))
- (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
-
-;; Stores and loads of ax to arbitrary 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"))
- (match_operand:DI 1 "nonmemory_operand" "a,er"))]
- "TARGET_64BIT && ix86_check_movabs (insn, 0)"
- "@
- movabs{q}\t{%1, %P0|%P0, %1}
- mov{q}\t{%1, %a0|%a0, %1}"
- [(set_attr "type" "imov")
- (set_attr "modrm" "0,*")
- (set_attr "length_address" "8,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 && ix86_check_movabs (insn, 1)"
- "@
- 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 through 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.
-;; "&& 1" is needed to keep it from matching the previous pattern.
-(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[0], 2, &operands[2], &operands[4]);")
-
-(define_split
- [(set (match_operand:DI 0 "memory_operand" "")
- (match_operand:DI 1 "immediate_operand" ""))]
- "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
- ? epilogue_completed : reload_completed)
- && !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[0], 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 "mode" "DI")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")
- (set_attr "amdfam10_decode" "double")])
-
-(define_expand "movoi"
- [(set (match_operand:OI 0 "nonimmediate_operand" "")
- (match_operand:OI 1 "general_operand" ""))]
- "TARGET_AVX"
- "ix86_expand_move (OImode, operands); DONE;")
-
-(define_insn "*movoi_internal"
- [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
- (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
- "TARGET_AVX
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (which_alternative)
- {
- case 0:
- return "vxorps\t%0, %0, %0";
- case 1:
- case 2:
- if (misaligned_operand (operands[0], OImode)
- || misaligned_operand (operands[1], OImode))
- return "vmovdqu\t{%1, %0|%0, %1}";
- else
- return "vmovdqa\t{%1, %0|%0, %1}";
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "sselog1,ssemov,ssemov")
- (set_attr "prefix" "vex")
- (set_attr "mode" "OI")])
-
-(define_expand "movti"
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (match_operand:TI 1 "nonimmediate_operand" ""))]
- "TARGET_SSE || TARGET_64BIT"
-{
- if (TARGET_64BIT)
- ix86_expand_move (TImode, operands);
- else if (push_operand (operands[0], TImode))
- ix86_expand_push (TImode, operands[1]);
- else
- ix86_expand_vector_move (TImode, operands);
- DONE;
-})
-
-(define_insn "*movti_internal"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
- (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
- "TARGET_SSE && !TARGET_64BIT
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (which_alternative)
- {
- case 0:
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
- case 1:
- case 2:
- /* TDmode values are passed as TImode on the stack. Moving them
- to stack may result in unaligned memory access. */
- if (misaligned_operand (operands[0], TImode)
- || misaligned_operand (operands[1], TImode))
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
- }
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "sselog1,ssemov,ssemov")
- (set_attr "prefix" "maybe_vex")
- (set (attr "mode")
- (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
- (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
- (const_string "V4SF")
- (and (eq_attr "alternative" "2")
- (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
- (const_int 0)))
- (const_string "V4SF")]
- (const_string "TI")))])
-
-(define_insn "*movti_rex64"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
- (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
- "TARGET_64BIT
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
-{
- switch (which_alternative)
- {
- case 0:
- case 1:
- return "#";
- case 2:
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vxorps\t%0, %d0";
- else
- return "%vpxor\t%0, %d0";
- case 3:
- case 4:
- /* TDmode values are passed as TImode on the stack. Moving them
- to stack may result in unaligned memory access. */
- if (misaligned_operand (operands[0], TImode)
- || misaligned_operand (operands[1], TImode))
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovups\t{%1, %0|%0, %1}";
- else
- return "%vmovdqu\t{%1, %0|%0, %1}";
- }
- else
- {
- if (get_attr_mode (insn) == MODE_V4SF)
- return "%vmovaps\t{%1, %0|%0, %1}";
- else
- return "%vmovdqa\t{%1, %0|%0, %1}";
- }
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
- (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
- (set (attr "mode")
- (cond [(eq_attr "alternative" "2,3")
- (if_then_else
- (ne (symbol_ref "optimize_function_for_size_p (cfun)")
- (const_int 0))
- (const_string "V4SF")
- (const_string "TI"))
- (eq_attr "alternative" "4")
- (if_then_else
- (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
- (const_int 0))
- (ne (symbol_ref "optimize_function_for_size_p (cfun)")
- (const_int 0)))
- (const_string "V4SF")
- (const_string "TI"))]
- (const_string "DI")))])
-
-(define_split
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (match_operand:TI 1 "general_operand" ""))]
- "reload_completed && !SSE_REG_P (operands[0])
- && !SSE_REG_P (operands[1])"
- [(const_int 0)]
- "ix86_split_long_move (operands); DONE;")
-
-;; This expands to what emit_move_complex would generate if we didn't
-;; have a movti pattern. Having this avoids problems with reload on
-;; 32-bit targets when SSE is present, but doesn't seem to be harmful
-;; to have around all the time.
-(define_expand "movcdi"
- [(set (match_operand:CDI 0 "nonimmediate_operand" "")
- (match_operand:CDI 1 "general_operand" ""))]
- ""
-{
- if (push_operand (operands[0], CDImode))
- emit_move_complex_push (CDImode, operands[0], operands[1]);
- else
- emit_move_complex_parts (operands[0], operands[1]);
- DONE;
-})
+
+;; Floating point move instructions.
(define_expand "movsf"
[(set (match_operand:SF 0 "nonimmediate_operand" "")
@@ -4137,7 +3886,7 @@
(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && reload_completed
- && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
+ && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 4) (const_int 0))]
"split_di (&operands[0], 1, &operands[3], &operands[4]);")
@@ -10520,7 +10269,7 @@
FAIL;
if (TARGET_64BIT)
- emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
+ emit_insn (gen_movdi_insv_1 (operands[0], operands[3]));
else
emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));