diff options
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r-- | gcc/config/i386/i386.md | 201 |
1 files changed, 121 insertions, 80 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a8ebfa48000..35273d95683 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -248,6 +248,9 @@ ;; For BMI2 support UNSPEC_PDEP UNSPEC_PEXT + + ;; For __atomic support + UNSPEC_MOVA ]) (define_c_enum "unspecv" [ @@ -262,7 +265,10 @@ UNSPECV_ALIGN UNSPECV_MONITOR UNSPECV_MWAIT - UNSPECV_CMPXCHG + UNSPECV_CMPXCHG_1 + UNSPECV_CMPXCHG_2 + UNSPECV_CMPXCHG_3 + UNSPECV_CMPXCHG_4 UNSPECV_XCHG UNSPECV_LOCK UNSPECV_PROLOGUE_USE @@ -2047,6 +2053,8 @@ return "mov{l}\t{%k1, %k0|%k0, %k1}"; else if (which_alternative == 2) return "movabs{q}\t{%1, %0|%0, %1}"; + else if (ix86_use_lea_for_mov (insn, operands)) + return "lea{q}\t{%a1, %0|%0, %a1}"; else return "mov{q}\t{%1, %0|%0, %1}"; } @@ -2282,7 +2290,10 @@ default: gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); - return "mov{l}\t{%1, %0|%0, %1}"; + if (ix86_use_lea_for_mov (insn, operands)) + return "lea{l}\t{%a1, %0|%0, %a1}"; + else + return "mov{l}\t{%1, %0|%0, %1}"; } } [(set (attr "type") @@ -4922,7 +4933,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(set (match_dup 0) (float:MODEF (match_dup 1)))]) (define_split @@ -4935,7 +4946,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (float:MODEF (match_dup 2)))]) @@ -5026,7 +5037,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(const_int 0)] { rtx op1 = operands[1]; @@ -5069,7 +5080,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(const_int 0)] { operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], @@ -5093,7 +5104,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(const_int 0)] { rtx op1 = operands[1]; @@ -5139,7 +5150,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(const_int 0)] { operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], @@ -5202,7 +5213,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(set (match_dup 0) (float:MODEF (match_dup 1)))]) (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit" @@ -5237,7 +5248,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (float:MODEF (match_dup 2)))]) @@ -5250,7 +5261,7 @@ && reload_completed && (SSE_REG_P (operands[0]) || (GET_CODE (operands[0]) == SUBREG - && SSE_REG_P (operands[0])))" + && SSE_REG_P (SUBREG_REG (operands[0]))))" [(set (match_dup 0) (float:MODEF (match_dup 1)))]) (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp" @@ -7702,8 +7713,10 @@ [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) (match_dup 3)) (const_int 0)]))] - "operands[2] = gen_lowpart (SImode, operands[2]); - operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);") +{ + operands[2] = gen_lowpart (SImode, operands[2]); + operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode); +}) (define_split [(set (match_operand 0 "flags_reg_operand" "") @@ -7721,8 +7734,10 @@ [(set (match_dup 0) (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) (const_int 0)]))] - "operands[2] = gen_lowpart (QImode, operands[2]); - operands[3] = gen_lowpart (QImode, operands[3]);") +{ + operands[2] = gen_lowpart (QImode, operands[2]); + operands[3] = gen_lowpart (QImode, operands[3]); +}) ;; %%% This used to optimize known byte-wide and operations to memory, ;; and sometimes to QImode registers. If this is considered useful, @@ -8147,9 +8162,11 @@ (const_int 8) (const_int 8)) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); +}) ;; Since AND can be encoded with sign extended immediate, this is only ;; profitable when 7th bit is not set. @@ -8168,9 +8185,11 @@ (and:QI (match_dup 1) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[0] = gen_lowpart (QImode, operands[0]); - operands[1] = gen_lowpart (QImode, operands[1]); - operands[2] = gen_lowpart (QImode, operands[2]);") +{ + operands[0] = gen_lowpart (QImode, operands[0]); + operands[1] = gen_lowpart (QImode, operands[1]); + operands[2] = gen_lowpart (QImode, operands[2]); +}) ;; Logical inclusive and exclusive OR instructions @@ -8402,9 +8421,11 @@ (const_int 8) (const_int 8)) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); +}) ;; Since OR can be encoded with sign extended immediate, this is only ;; profitable when 7th bit is set. @@ -8423,9 +8444,11 @@ (any_or:QI (match_dup 1) (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] - "operands[0] = gen_lowpart (QImode, operands[0]); - operands[1] = gen_lowpart (QImode, operands[1]); - operands[2] = gen_lowpart (QImode, operands[2]);") +{ + operands[0] = gen_lowpart (QImode, operands[0]); + operands[1] = gen_lowpart (QImode, operands[1]); + operands[2] = gen_lowpart (QImode, operands[2]); +}) (define_expand "xorqi_cc_ext_1" [(parallel [ @@ -14651,7 +14674,7 @@ else if (optimize_insn_for_size_p ()) FAIL; else - ix86_expand_rint (operand0, operand1); + ix86_expand_rint (operands[0], operands[1]); } else { @@ -14851,7 +14874,7 @@ && <SWI248x:MODE>mode != HImode && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) && !flag_trapping_math && !flag_rounding_math) - ix86_expand_lround (operand0, operand1); + ix86_expand_lround (operands[0], operands[1]); else ix86_emit_i387_round (operands[0], operands[1]); DONE; @@ -14927,9 +14950,9 @@ else if (optimize_insn_for_size_p ()) FAIL; else if (TARGET_64BIT || (<MODE>mode != DFmode)) - ix86_expand_floorceil (operand0, operand1, true); + ix86_expand_floorceil (operands[0], operands[1], true); else - ix86_expand_floorceildf_32 (operand0, operand1, true); + ix86_expand_floorceildf_32 (operands[0], operands[1], true); } else { @@ -15111,7 +15134,7 @@ { if (TARGET_64BIT && optimize_insn_for_size_p ()) FAIL; - ix86_expand_lfloorceil (operand0, operand1, true); + ix86_expand_lfloorceil (operands[0], operands[1], true); DONE; }) @@ -15185,9 +15208,9 @@ else if (optimize_insn_for_size_p ()) FAIL; else if (TARGET_64BIT || (<MODE>mode != DFmode)) - ix86_expand_floorceil (operand0, operand1, false); + ix86_expand_floorceil (operands[0], operands[1], false); else - ix86_expand_floorceildf_32 (operand0, operand1, false); + ix86_expand_floorceildf_32 (operands[0], operands[1], false); } else { @@ -15367,7 +15390,7 @@ "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH && !flag_trapping_math" { - ix86_expand_lfloorceil (operand0, operand1, false); + ix86_expand_lfloorceil (operands[0], operands[1], false); DONE; }) @@ -15441,9 +15464,9 @@ else if (optimize_insn_for_size_p ()) FAIL; else if (TARGET_64BIT || (<MODE>mode != DFmode)) - ix86_expand_trunc (operand0, operand1); + ix86_expand_trunc (operands[0], operands[1]); else - ix86_expand_truncdf_32 (operand0, operand1); + ix86_expand_truncdf_32 (operands[0], operands[1]); } else { @@ -16631,14 +16654,18 @@ ;; The % modifier is not operational anymore in peephole2's, so we have to ;; swap the operands manually in the case of addition and multiplication. - "if (COMMUTATIVE_ARITH_P (operands[2])) - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), - GET_MODE (operands[2]), - operands[0], operands[1]); - else - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), - GET_MODE (operands[2]), - operands[1], operands[0]);") +{ + rtx op0, op1; + + if (COMMUTATIVE_ARITH_P (operands[2])) + op0 = operands[0], op1 = operands[1]; + else + op0 = operands[1], op1 = operands[0]; + + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), + GET_MODE (operands[2]), + op0, op1); +}) ;; Conditional addition patterns (define_expand "add<mode>cc" @@ -16837,11 +16864,13 @@ [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)])) (clobber (reg:CC FLAGS_REG))])] - "operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - if (GET_CODE (operands[3]) != ASHIFT) - operands[2] = gen_lowpart (SImode, operands[2]); - PUT_MODE (operands[3], SImode);") +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + if (GET_CODE (operands[3]) != ASHIFT) + operands[2] = gen_lowpart (SImode, operands[2]); + PUT_MODE (operands[3], SImode); +}) ; Promote the QImode tests, as i386 has encoding of the AND ; instruction with 32-bit sign-extended immediate and thus the @@ -16911,8 +16940,10 @@ [(parallel [(set (match_dup 0) (neg:SI (match_dup 1))) (clobber (reg:CC FLAGS_REG))])] - "operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]);") +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); +}) (define_split [(set (match_operand 0 "register_operand" "") @@ -16924,8 +16955,10 @@ || optimize_insn_for_size_p ())))" [(set (match_dup 0) (not:SI (match_dup 1)))] - "operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]);") +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); +}) (define_split [(set (match_operand 0 "register_operand" "") @@ -16940,9 +16973,11 @@ || optimize_insn_for_size_p ())))" [(set (match_dup 0) (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "operands[0] = gen_lowpart (SImode, operands[0]); - operands[2] = gen_lowpart (SImode, operands[2]); - operands[3] = gen_lowpart (SImode, operands[3]);") +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[2] = gen_lowpart (SImode, operands[2]); + operands[3] = gen_lowpart (SImode, operands[3]); +}) ;; RTL Peephole optimizations, run before sched2. These primarily look to ;; transform a complex memory operation into two memory to register operations. @@ -17228,12 +17263,14 @@ [(parallel [(set (match_dup 4) (match_dup 5)) (set (match_dup 1) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))])] - "operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, - copy_rtx (operands[1]), - copy_rtx (operands[2])); - operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), - operands[5], const0_rtx);") +{ + operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, + copy_rtx (operands[1]), + copy_rtx (operands[2])); + operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), + operands[5], const0_rtx); +}) (define_peephole2 [(parallel [(set (match_operand:SWI 0 "register_operand" "") @@ -17253,12 +17290,14 @@ [(parallel [(set (match_dup 3) (match_dup 4)) (set (match_dup 1) (match_op_dup 2 [(match_dup 1) (match_dup 0)]))])] - "operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode, - copy_rtx (operands[1]), - copy_rtx (operands[0])); - operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]), - operands[4], const0_rtx);") +{ + operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode, + copy_rtx (operands[1]), + copy_rtx (operands[0])); + operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]), + operands[4], const0_rtx); +}) (define_peephole2 [(set (match_operand:SWI12 0 "register_operand" "") @@ -17281,15 +17320,17 @@ ? CCGOCmode : CCNOmode)" [(parallel [(set (match_dup 4) (match_dup 5)) (set (match_dup 1) (match_dup 6))])] - "operands[2] = gen_lowpart (<MODE>mode, operands[2]); - operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, - copy_rtx (operands[1]), operands[2]); - operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), - operands[5], const0_rtx); - operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, - copy_rtx (operands[1]), - copy_rtx (operands[2]));") +{ + operands[2] = gen_lowpart (<MODE>mode, operands[2]); + operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, + copy_rtx (operands[1]), operands[2]); + operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), + operands[5], const0_rtx); + operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, + copy_rtx (operands[1]), + copy_rtx (operands[2])); +}) ;; Attempt to always use XOR for zeroing registers. (define_peephole2 @@ -18075,8 +18116,8 @@ (match_operand:SI 3 "const_int_operand" "i")] UNSPECV_LWPVAL_INTRINSIC)] "TARGET_LWP" - "/* Avoid unused variable warning. */ - (void) operand0;") + ;; Avoid unused variable warning. + "(void) operands[0];") (define_insn "*lwp_lwpval<mode>3_1" [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") |