summaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r--gcc/config/i386/i386.md201
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")