;; Z -- likewise, with special suffixes for x87 instructions.
;; * -- print a star (in certain assembler syntax)
;; A -- print an absolute memory reference.
+;; E -- print address with DImode register names if TARGET_64BIT.
;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
;; s -- print a shift double count, followed by the assemblers argument
;; delimiter.
;; Prologue support
UNSPEC_STACK_ALLOC
UNSPEC_SET_GOT
- UNSPEC_REG_SAVE
- UNSPEC_DEF_CFA
UNSPEC_SET_RIP
UNSPEC_SET_GOT_OFFSET
UNSPEC_MEMORY_BLOCKAGE
UNSPEC_MS_TO_SYSV_CALL
UNSPEC_CALL_NEEDS_VZEROUPPER
UNSPEC_PAUSE
+ UNSPEC_LEA_ADDR
;; For SSE/MMX support:
UNSPEC_FIX_NOTRUNC
;; For CRC32 support
UNSPEC_CRC32
- ;; For RDRAND support
- UNSPEC_RDRAND
-
;; For BMI support
UNSPEC_BEXTR
UNSPECV_RDGSBASE
UNSPECV_WRFSBASE
UNSPECV_WRGSBASE
+
+ ;; For RDRAND support
+ UNSPECV_RDRAND
])
;; Constants to represent rounding modes in the ROUND instruction
(define_attr "movu" "0,1" (const_string "0"))
;; Used to control the "enabled" attribute on a per-instruction basis.
-(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
+(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
+ bmi2,fma,fma4"
(const_string "base"))
(define_attr "enabled" ""
(eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
(eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
(eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
+ (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
+ ;; Fma instruction selection has to be done based on
+ ;; register pressure. For generating fma4, a cost model
+ ;; based on register pressure is required. Till then,
+ ;; fma4 instruction is disabled for targets that implement
+ ;; both fma and fma4 instruction sets.
+ (eq_attr "isa" "fma4")
+ (symbol_ref "TARGET_FMA4 && !TARGET_FMA")
]
(const_int 1)))
return "#";
case TYPE_LEA:
- return "lea{q}\t{%a1, %0|%0, %a1}";
+ return "lea{q}\t{%E1, %0|%0, %E1}";
default:
gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
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}";
+ return "lea{q}\t{%E1, %0|%0, %E1}";
else
return "mov{q}\t{%1, %0|%0, %1}";
}
return "movd\t{%1, %0|%0, %1}";
case TYPE_LEA:
- return "lea{l}\t{%a1, %0|%0, %a1}";
+ return "lea{l}\t{%E1, %0|%0, %E1}";
default:
gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
if (ix86_use_lea_for_mov (insn, operands))
- return "lea{l}\t{%a1, %0|%0, %a1}";
+ return "lea{l}\t{%E1, %0|%0, %E1}";
else
return "mov{l}\t{%1, %0|%0, %1}";
}
(const_int 8))
(match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
"TARGET_64BIT"
- "mov{b}\t{%b1, %h0|%h0, %b1}"
+{
+ if (CONST_INT_P (operands[1]))
+ operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
+ return "mov{b}\t{%b1, %h0|%h0, %b1}";
+}
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
(const_int 8))
(match_operand:SI 1 "general_operand" "Qmn"))]
"!TARGET_64BIT"
- "mov{b}\t{%b1, %h0|%h0, %b1}"
+{
+ if (CONST_INT_P (operands[1]))
+ operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
+ return "mov{b}\t{%b1, %h0|%h0, %b1}";
+}
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
DONE;
})
\f
+;; Load effective address instructions
+
+(define_insn_and_split "*lea<mode>"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (match_operand:SWI48 1 "lea_address_operand" "p"))]
+ ""
+{
+ rtx addr = operands[1];
+
+ if (SImode_address_operand (addr, VOIDmode))
+ {
+ gcc_assert (TARGET_64BIT);
+ return "lea{l}\t{%E1, %k0|%k0, %E1}";
+ }
+ else
+ return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
+}
+ "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
+ [(const_int 0)]
+{
+ ix86_split_lea_for_addr (operands, <MODE>mode);
+ DONE;
+}
+ [(set_attr "type" "lea")
+ (set (attr "mode")
+ (if_then_else
+ (match_operand 1 "SImode_address_operand")
+ (const_string "SI")
+ (const_string "<MODE>")))])
+\f
;; Add instructions
(define_expand "add<mode>3"
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
-(define_insn_and_split "*lea_1"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
- "TARGET_64BIT"
- "lea{l}\t{%a1, %0|%0, %a1}"
- "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
- [(const_int 0)]
-{
- ix86_split_lea_for_addr (operands, SImode);
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn_and_split "*lea<mode>_2"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
- (match_operand:SWI48 1 "lea_address_operand" "p"))]
- ""
- "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
- "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
- [(const_int 0)]
-{
- ix86_split_lea_for_addr (operands, <MODE>mode);
- DONE;
-}
- [(set_attr "type" "lea")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*lea_3_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
- "TARGET_64BIT"
- "lea{l}\t{%a1, %k0|%k0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn "*lea_4_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (match_operand:SI 1 "lea_address_operand" "j")))]
- "TARGET_64BIT"
- "lea{l}\t{%a1, %k0|%k0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn "*lea_5_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI
- (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
- (match_operand:DI 2 "const_32bit_mask" "n")))]
- "TARGET_64BIT"
- "lea{l}\t{%a1, %k0|%k0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
-(define_insn "*lea_6_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI
- (match_operand:DI 1 "lea_address_operand" "p")
- (match_operand:DI 2 "const_32bit_mask" "n")))]
- "TARGET_64BIT"
- "lea{l}\t{%a1, %k0|%k0, %a1}"
- [(set_attr "type" "lea")
- (set_attr "mode" "SI")])
-
(define_insn "*add<mode>_1"
[(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
(plus:SWI48
(and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
(match_operand:SWIM 2 "<general_szext_operand>" "")))]
""
- "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
+{
+ if (<MODE>mode == DImode
+ && GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
+ && REG_P (operands[1]))
+ emit_insn (gen_zero_extendsidi2 (operands[0],
+ gen_lowpart (SImode, operands[1])));
+ else
+ ix86_expand_binary_operator (AND, <MODE>mode, operands);
+ DONE;
+})
(define_insn "*anddi_1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
"!TARGET_64BIT && TARGET_GNU_TLS"
{
output_asm_insn
- ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
+ ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
if (TARGET_SUN_TLS)
#ifdef HAVE_AS_IX86_TLSGDPLT
return "call\t%a2@tlsgdplt";
if (!TARGET_X32)
fputs (ASM_BYTE "0x66\n", asm_out_file);
output_asm_insn
- ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
+ ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
fputs (ASM_SHORT "0x6666\n", asm_out_file);
fputs ("\trex64\n", asm_out_file);
if (TARGET_SUN_TLS)
(unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
UNSPEC_TLSDESC))))]
"!TARGET_64BIT && TARGET_GNU2_TLS"
- "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
+ "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")
(set_attr "length" "6")
(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
UNSPEC_TLSDESC))]
"TARGET_64BIT && TARGET_GNU2_TLS"
- "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
+ "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
[(set_attr "type" "lea")
(set_attr "mode" "DI")
(set_attr "length" "7")
(define_insn "*x86_mov<mode>cc_0_m1_neg"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
- [(reg FLAGS_REG) (const_int 0)])))]
+ [(reg FLAGS_REG) (const_int 0)])))
+ (clobber (reg:CC FLAGS_REG))]
""
"sbb{<imodesuffix>}\t%0, %0"
[(set_attr "type" "alu")
[(set_attr "type" "icmov")
(set_attr "mode" "<MODE>")])
-(define_insn_and_split "*movqicc_noc"
+(define_insn "*movqicc_noc"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
- [(match_operand 4 "flags_reg_operand" "")
- (const_int 0)])
+ [(reg FLAGS_REG) (const_int 0)])
(match_operand:QI 2 "register_operand" "r,0")
(match_operand:QI 3 "register_operand" "0,r")))]
"TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
"#"
- "&& reload_completed"
- [(set (match_dup 0)
- (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
- (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]);"
[(set_attr "type" "icmov")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "QI")])
+
+(define_split
+ [(set (match_operand 0 "register_operand")
+ (if_then_else (match_operator 1 "ix86_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand 2 "register_operand")
+ (match_operand 3 "register_operand")))]
+ "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
+ && (GET_MODE (operands[0]) == QImode
+ || GET_MODE (operands[0]) == HImode)
+ && reload_completed"
+ [(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]);
+})
(define_expand "mov<mode>cc"
[(set (match_operand:X87MODEF 0 "register_operand" "")
(set_attr "mode" "DF,DF,DI,DI")])
(define_split
- [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
+ [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
- [(match_operand 4 "flags_reg_operand" "")
- (const_int 0)])
- (match_operand:DF 2 "nonimmediate_operand" "")
- (match_operand:DF 3 "nonimmediate_operand" "")))]
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand:DF 2 "nonimmediate_operand")
+ (match_operand:DF 3 "nonimmediate_operand")))]
"!TARGET_64BIT && reload_completed"
[(set (match_dup 2)
- (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
- (match_dup 5)
- (match_dup 6)))
+ (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
(set (match_dup 3)
- (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
- (match_dup 7)
- (match_dup 8)))]
+ (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
{
- split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
+ split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
})
default:
operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
- return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
+ return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
}
}
[(set (attr "type")
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
})
-
-(define_split
- [(set (match_operand 0 "register_operand" "")
- (if_then_else (match_operator 1 "ordered_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand 2 "register_operand" "")
- (match_operand 3 "register_operand" "")))]
- "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
- && (GET_MODE (operands[0]) == HImode
- || (GET_MODE (operands[0]) == QImode
- && (TARGET_PROMOTE_QImode
- || 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]);
-})
\f
;; RTL Peephole optimizations, run before sched2. These primarily look to
;; transform a complex memory operation into two memory to register operations.
"(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
&& peep2_reg_dead_p (4, operands[0])
&& !reg_overlap_mentioned_p (operands[0], operands[1])
+ && (<MODE>mode != QImode
+ || immediate_operand (operands[2], QImode)
+ || q_regs_operand (operands[2], QImode))
&& ix86_match_ccmode (peep2_next_insn (3),
(GET_CODE (operands[3]) == PLUS
|| GET_CODE (operands[3]) == MINUS)
int locality = INTVAL (operands[2]);
gcc_assert (rw == 0 || rw == 1);
- gcc_assert (locality >= 0 && locality <= 3);
- gcc_assert (GET_MODE (operands[0]) == Pmode
- || GET_MODE (operands[0]) == VOIDmode);
+ gcc_assert (IN_RANGE (locality, 0, 3));
+ if (TARGET_PREFETCHW && rw)
+ operands[2] = GEN_INT (3);
/* Use 3dNOW prefetch in case we are asking for write prefetch not
supported by SSE counterpart or the SSE prefetch is not available
(K6 machines). Otherwise use SSE prefetch as it allows specifying
of locality. */
- if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
+ else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
operands[2] = GEN_INT (3);
else
operands[1] = const0_rtx;
})
-(define_insn "*prefetch_sse_<mode>"
- [(prefetch (match_operand:P 0 "address_operand" "p")
+(define_insn "*prefetch_sse"
+ [(prefetch (match_operand 0 "address_operand" "p")
(const_int 0)
(match_operand:SI 1 "const_int_operand" ""))]
"TARGET_PREFETCH_SSE"
};
int locality = INTVAL (operands[1]);
- gcc_assert (locality >= 0 && locality <= 3);
+ gcc_assert (IN_RANGE (locality, 0, 3));
return patterns[locality];
}
[(set_attr "type" "sse")
(set_attr "atom_sse_attr" "prefetch")
(set (attr "length_address")
- (symbol_ref "memory_address_length (operands[0])"))
+ (symbol_ref "memory_address_length (operands[0], false)"))
(set_attr "memory" "none")])
-(define_insn "*prefetch_3dnow_<mode>"
- [(prefetch (match_operand:P 0 "address_operand" "p")
+(define_insn "*prefetch_3dnow"
+ [(prefetch (match_operand 0 "address_operand" "p")
(match_operand:SI 1 "const_int_operand" "n")
(const_int 3))]
- "TARGET_3DNOW"
+ "TARGET_3DNOW || TARGET_PREFETCHW"
{
if (INTVAL (operands[1]) == 0)
return "prefetch\t%a0";
}
[(set_attr "type" "mmx")
(set (attr "length_address")
- (symbol_ref "memory_address_length (operands[0])"))
+ (symbol_ref "memory_address_length (operands[0], false)"))
(set_attr "memory" "none")])
(define_expand "stack_protect_set"
[(match_operand 0 "memory_operand" "")
(match_operand 1 "memory_operand" "")]
- ""
+ "!TARGET_HAS_BIONIC"
{
rtx (*insn)(rtx, rtx);
UNSPEC_SP_SET))
(set (match_scratch:PTR 2 "=&r") (const_int 0))
(clobber (reg:CC FLAGS_REG))]
- ""
+ "!TARGET_HAS_BIONIC"
"mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
[(set_attr "type" "multi")])
[(match_operand 0 "memory_operand" "")
(match_operand 1 "memory_operand" "")
(match_operand 2 "" "")]
- ""
+ "!TARGET_HAS_BIONIC"
{
rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
(match_operand:PTR 2 "memory_operand" "m")]
UNSPEC_SP_TEST))
(clobber (match_scratch:PTR 3 "=&r"))]
- ""
+ "!TARGET_HAS_BIONIC"
"mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
[(set_attr "type" "multi")])
(define_insn "rdrand<mode>_1"
[(set (match_operand:SWI248 0 "register_operand" "=r")
- (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
+ (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
(set (reg:CCC FLAGS_REG)
- (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
+ (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
"TARGET_RDRND"
"rdrand\t%0"
[(set_attr "type" "other")