{
if (!flag_pic)
return false;
+
/* Rule out relocations that translate into 64bit constants. */
if (TARGET_64BIT && GET_CODE (op) == CONST)
{
|| XINT (op, 1) == UNSPEC_GOT))
return false;
}
+
return symbolic_operand (op, mode);
})
-
;; Return true if OP is nonmemory operand acceptable by movabs patterns.
(define_predicate "x86_64_movabs_operand"
- (if_then_else (not (and (match_test "TARGET_64BIT")
- (match_test "flag_pic")))
- (match_operand 0 "nonmemory_operand")
- (ior (match_operand 0 "register_operand")
- (and (match_operand 0 "const_double_operand")
- (match_test "GET_MODE_SIZE (mode) <= 8")))))
+ (and (match_operand 0 "nonmemory_operand")
+ (not (match_operand 0 "pic_32bit_operand"))))
;; Return true if OP is either a symbol reference or a sum of a symbol
;; reference and a constant.
|| (GET_CODE (op) == UNSPEC
&& (XINT (op, 1) == UNSPEC_GOT
|| XINT (op, 1) == UNSPEC_GOTOFF
+ || XINT (op, 1) == UNSPEC_PCREL
|| XINT (op, 1) == UNSPEC_GOTPCREL)))
return true;
if (GET_CODE (op) != PLUS
(and (match_code "symbol_ref")
(match_test "op == ix86_tls_module_base ()")))
-(define_predicate "tp_or_register_operand"
- (ior (match_operand 0 "register_operand")
- (and (match_code "unspec")
- (match_test "XINT (op, 1) == UNSPEC_TP"))))
-
;; Test for a pc-relative call operand
(define_predicate "constant_call_address_operand"
(match_code "symbol_ref")
(ior (match_operand 0 "register_no_elim_operand")
(match_operand 0 "immediate_operand")))
+;; Test for a valid operand for indirect branch.
+(define_predicate "indirect_branch_operand"
+ (if_then_else (match_test "TARGET_X32")
+ (match_operand 0 "register_operand")
+ (match_operand 0 "nonimmediate_operand")))
+
;; Test for a valid operand for a call instruction.
(define_predicate "call_insn_operand"
(ior (match_operand 0 "constant_call_address_operand")
(match_operand 0 "call_register_no_elim_operand")
- (match_operand 0 "memory_operand")))
+ (and (not (match_test "TARGET_X32"))
+ (match_operand 0 "memory_operand"))))
;; Similarly, but for tail calls, in which we cannot allow memory references.
(define_predicate "sibcall_insn_operand"
(and (match_code "const_int")
(match_test "INTVAL (op) == 128")))
+;; Match exactly 0x0FFFFFFFF in anddi as a zero-extension operation
+(define_predicate "const_32bit_mask"
+ (and (match_code "const_int")
+ (match_test "trunc_int_for_mode (INTVAL (op), DImode)
+ == (HOST_WIDE_INT) 0xffffffff")))
+
;; Match 2, 4, or 8. Used for leal multiplicands.
(define_predicate "const248_operand"
(match_code "const_int")
return i == 2 || i == 4 || i == 8;
})
+;; Match 1, 2, 4, or 8
+(define_predicate "const1248_operand"
+ (match_code "const_int")
+{
+ HOST_WIDE_INT i = INTVAL (op);
+ return i == 1 || i == 2 || i == 4 || i == 8;
+})
+
+;; Match 3, 5, or 9. Used for leal multiplicands.
+(define_predicate "const359_operand"
+ (match_code "const_int")
+{
+ HOST_WIDE_INT i = INTVAL (op);
+ return i == 3 || i == 5 || i == 9;
+})
+
;; Match 0 or 1.
(define_predicate "const_0_to_1_operand"
(and (match_code "const_int")
(ior (match_operand 0 "register_operand")
(match_operand 0 "const0_operand")))
-;; Return true if op if a valid address, and does not contain
-;; a segment override.
-(define_special_predicate "no_seg_address_operand"
+;; Return true if op if a valid address for LEA, and does not contain
+;; a segment override. Defined as a special predicate to allow
+;; mode-less const_int operands pass to address_operand.
+(define_special_predicate "lea_address_operand"
(match_operand 0 "address_operand")
{
struct ix86_address parts;
return parts.seg == SEG_DEFAULT;
})
+;; Return true for RTX codes that force SImode address.
+(define_predicate "SImode_address_operand"
+ (match_code "subreg,zero_extend,and"))
+
+;; Return true if op if a valid base register, displacement or
+;; sum of base register and displacement for VSIB addressing.
+(define_predicate "vsib_address_operand"
+ (match_operand 0 "address_operand")
+{
+ struct ix86_address parts;
+ int ok;
+ rtx disp;
+
+ ok = ix86_decompose_address (op, &parts);
+ gcc_assert (ok);
+ if (parts.index || parts.seg != SEG_DEFAULT)
+ return false;
+
+ /* VSIB addressing doesn't support (%rip). */
+ if (parts.disp && GET_CODE (parts.disp) == CONST)
+ {
+ disp = XEXP (parts.disp, 0);
+ if (GET_CODE (disp) == PLUS)
+ disp = XEXP (disp, 0);
+ if (GET_CODE (disp) == UNSPEC)
+ switch (XINT (disp, 1))
+ {
+ case UNSPEC_GOTPCREL:
+ case UNSPEC_PCREL:
+ case UNSPEC_GOTNTPOFF:
+ return false;
+ }
+ }
+
+ return true;
+})
+
+(define_predicate "vsib_mem_operator"
+ (match_code "mem"))
+
;; Return true if the rtx is known to be at least 32 bits aligned.
(define_predicate "aligned_operand"
(match_operand 0 "general_operand")
ok = ix86_decompose_address (op, &parts);
gcc_assert (ok);
+ if (parts.base && GET_CODE (parts.base) == SUBREG)
+ parts.base = SUBREG_REG (parts.base);
+ if (parts.index && GET_CODE (parts.index) == SUBREG)
+ parts.index = SUBREG_REG (parts.index);
+
/* Look for some component that isn't known to be aligned. */
if (parts.index)
{
struct ix86_address parts;
int ok;
+ if (TARGET_64BIT || !flag_pic)
+ return true;
+
ok = ix86_decompose_address (XEXP (op, 0), &parts);
gcc_assert (ok);
+
+ if (parts.base && GET_CODE (parts.base) == SUBREG)
+ parts.base = SUBREG_REG (parts.base);
+ if (parts.index && GET_CODE (parts.index) == SUBREG)
+ parts.index = SUBREG_REG (parts.index);
+
if (parts.base == NULL_RTX
|| parts.base == arg_pointer_rtx
|| parts.base == frame_pointer_rtx
;; by the modRM array.
(define_predicate "long_memory_operand"
(and (match_operand 0 "memory_operand")
- (match_test "memory_address_length (op)")))
+ (match_test "memory_address_length (op, false)")))
;; Return true if OP is a comparison operator that can be issued by fcmov.
(define_predicate "fcmov_comparison_operator"
;; Return true if OP is a binary operator that can be promoted to wider mode.
(define_predicate "promotable_binary_operator"
- (ior (match_code "plus,and,ior,xor,ashift")
+ (ior (match_code "plus,minus,and,ior,xor,ashift")
(and (match_code "mult")
(match_test "TARGET_TUNE_PROMOTE_HIMODE_IMUL"))))
return false;
return true;
})
+
+;; Return true if OP is a proper third operand to vpblendw256.
+(define_predicate "avx2_pblendw_operand"
+ (match_code "const_int")
+{
+ HOST_WIDE_INT val = INTVAL (op);
+ HOST_WIDE_INT low = val & 0xff;
+ return val == ((low << 8) | low);
+})