"Address operand without segment register"
(match_operand 0 "address_no_seg_operand"))
+;; j prefix is used for APX operand constraints.
+;; < Auto-dec memory operand without GPR32.
+;; > Auto-inc memory operand without GPR32.
+;; a Vector memory operand without GPR32.
+;; b VSIB address operand without EGPR.
+;; c Integer register. GENERAL_GPR16 for TARGET_APX_EGPR and
+;; !TARGET_AVX, otherwise GENERAL_REGS.
+;; e Memory operand for APX NDD ADD.
+;; j Integer register. GENERAL_GPR16 for TARGET_APX_EGPR, otherwise
+;; GENERAL_REGS.
+;; o Offsetable memory operand without GPR32.
+;; p General address operand without GPR32.
+;; m Memory operand without GPR32.
+;; M Memory operand, with APX NDD check.
+;; R Integer register. GENERAL_REGS.
+;; O Offsettable memory operand, with APX NDD check.
+;; V Non-offsetable memory operand without GPR32.
+
;; Constraint that force to use EGPR, can only adopt to register class.
(define_register_constraint "jR" "GENERAL_REGS")
(match_test "x86_extended_rex2reg_mentioned_p (op)")))))
(define_constraint "j>"
- "@internal auto-dec memory operand without GPR32."
+ "@internal auto-inc memory operand without GPR32."
(and (and (match_code "mem")
(ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_INC")
(match_test "GET_CODE (XEXP (op, 0)) == POST_INC")))
(define_register_constraint "jc"
"TARGET_APX_EGPR && !TARGET_AVX ? GENERAL_GPR16 : GENERAL_REGS")
-(define_constraint "je"
- "@internal constant that do not allow any unspec global offsets"
- (and (match_operand 0 "x86_64_immediate_operand")
- (match_test "!x86_poff_operand_p (op)")))
+(define_memory_constraint "je"
+ "@internal Memory operand for APX NDD ADD."
+ (match_operand 0 "apx_ndd_add_memory_operand"))
+
+(define_memory_constraint "jM"
+ "@internal Memory operand, with APX NDD check."
+ (match_operand 0 "apx_ndd_memory_operand"))
+
+(define_memory_constraint "jO"
+ "@internal Offsettable memory operand, with APX NDD check."
+ (and (match_operand 0 "apx_ndd_memory_operand")
+ (match_test "offsettable_nonstrict_memref_p (op)")))
extern bool x86_extended_reg_mentioned_p (rtx);
extern bool x86_extended_rex2reg_mentioned_p (rtx);
extern bool x86_evex_reg_mentioned_p (rtx [], int);
-extern bool x86_poff_operand_p (rtx);
extern bool x86_maybe_negate_const_int (rtx *, machine_mode);
extern machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
return false;
}
-/* Return true when rtx operand does not contain any UNSPEC_*POFF related
- constant to avoid APX_NDD instructions excceed encoding length limit. */
-bool
-x86_poff_operand_p (rtx operand)
-{
- if (GET_CODE (operand) == CONST)
- {
- rtx op = XEXP (operand, 0);
- if (GET_CODE (op) == PLUS)
- op = XEXP (op, 0);
-
- if (GET_CODE (op) == UNSPEC)
- {
- int unspec = XINT (op, 1);
- return (unspec == UNSPEC_NTPOFF
- || unspec == UNSPEC_TPOFF
- || unspec == UNSPEC_DTPOFF
- || unspec == UNSPEC_GOTTPOFF
- || unspec == UNSPEC_GOTNTPOFF
- || unspec == UNSPEC_INDNTPOFF);
- }
- }
- return false;
-}
-
/* If profitable, negate (without causing overflow) integer constant
of mode MODE at location LOC. Return true in this case. */
bool
})
(define_insn_and_split "*add<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r")
(plus:<DWI>
- (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
- (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,r")))
+ (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,rjO,r")
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,r")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
"#"
DONE;
}
}
-[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")])
(define_insn_and_split "*add<dwi>3_doubleword_zext"
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
"split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
(define_insn "*add<mode>_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r,r")
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r")
(plus:SWI48
- (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rm,r,m,r")
- (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,r,e,je,BM")))
+ (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rje,jM,r")
+ (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,r,e,BM")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
{
: "add{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
- [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd")
+ [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd")
(set (attr "type")
(cond [(eq_attr "alternative" "3")
(const_string "lea")
;; patterns constructed from addsi_1 to match.
(define_insn "addsi_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r")
(zero_extend:DI
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm")
- (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,re"))))
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm,rjM")
+ (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,r,e"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT
&& ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
: "add{l}\t{%2, %k0|%k0, %2}";
}
}
- [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
+ [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
(set (attr "type")
(cond [(eq_attr "alternative" "2")
(const_string "lea")
(eq:CCO
(plus:<QPWI>
(sign_extend:<QPWI>
- (match_operand:<DWI> 1 "nonimmediate_operand" "%0,rm"))
+ (match_operand:<DWI> 1 "nonimmediate_operand" "%0,rjM"))
(match_operand:<QPWI> 3 "const_scalar_int_operand" "n,n"))
(sign_extend:<QPWI>
(plus:<DWI>
[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
(define_insn "*sub<mode>_1"
- [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
+ [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
(minus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
+ (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,rjM,r")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
"@
sub{<imodesuffix>}\t{%2, %0|%0, %2}
sub{<imodesuffix>}\t{%2, %0|%0, %2}
sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+ sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+ [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
[(set (reg:CCC FLAGS_REG)
(compare:CCC
(plus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
+ (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,rjM,r")
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r,<i>,<m>"))
(match_dup 1)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r")
(plus:SWI (match_dup 1) (match_dup 2)))]
"ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
"@
add{<imodesuffix>}\t{%2, %0|%0, %2}
add{<imodesuffix>}\t{%2, %0|%0, %2}
add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+ add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+ [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")
(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
[(set (reg:CCC FLAGS_REG)
(compare:CCC
(plus:<DWI>
- (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
- (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o"))
+ (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,rjO,r")
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,o"))
(match_dup 1)))
- (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
+ (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r")
(plus:<DWI> (match_dup 1) (match_dup 2)))]
"ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
"#"
else
operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
}
-[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")])
;; x == 0 with zero flag test can be done also as x < 1U with carry flag
;; test, where the latter is preferrable if we have some carry consuming
})
(define_insn_and_split "*and<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r")
(and:<DWI>
- (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
- (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
+ (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,rjO,r")
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,o")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (AND, <DWI>mode, operands, TARGET_APX_NDD)"
"#"
DONE;
}
-[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")])
(define_insn "*anddi_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,?k")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,r,?k")
(and:DI
- (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,r,qm,k")
- (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,re,m,L,k")))
+ (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,rjM,r,qm,k")
+ (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,r,e,m,L,k")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT
&& ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
and{q}\t{%2, %0|%0, %2}
and{q}\t{%2, %1, %0|%0, %1, %2}
and{q}\t{%2, %1, %0|%0, %1, %2}
+ and{q}\t{%2, %1, %0|%0, %1, %2}
#
#"
- [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,x64,avx512bw")
- (set_attr "type" "alu,alu,alu,alu,alu,alu,imovx,msklog")
- (set_attr "length_immediate" "*,*,*,*,*,*,0,*")
+ [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,apx_ndd,x64,avx512bw")
+ (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,imovx,msklog")
+ (set_attr "length_immediate" "*,*,*,*,*,*,*,0,*")
(set (attr "prefix_rex")
(if_then_else
(and (eq_attr "type" "imovx")
(match_operand 1 "ext_QIreg_operand")))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "SI,SI,DI,DI,DI,DI,SI,DI")])
+ (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,SI,DI")])
(define_insn_and_split "*anddi_1_btr"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*andsi_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
(zero_extend:DI
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
- (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))))
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
+ (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT
&& ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
"@
and{l}\t{%2, %k0|%k0, %2}
and{l}\t{%2, %1, %k0|%k0, %1, %2}
+ and{l}\t{%2, %1, %k0|%k0, %1, %2}
and{l}\t{%2, %1, %k0|%k0, %1, %2}"
[(set_attr "type" "alu")
- (set_attr "isa" "*,apx_ndd,apx_ndd")
+ (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
(set_attr "mode" "SI")])
(define_insn "*and<mode>_1"
- [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,Ya,?k")
- (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,r,qm,k")
- (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,L,k")))
+ [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,r,Ya,?k")
+ (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,rjM,r,qm,k")
+ (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,L,k")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
"@
and{<imodesuffix>}\t{%2, %0|%0, %2}
and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+ and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
#
#"
[(set (attr "isa")
- (cond [(eq_attr "alternative" "2,3")
+ (cond [(eq_attr "alternative" "2,3,4")
(const_string "apx_ndd")
- (eq_attr "alternative" "5")
+ (eq_attr "alternative" "6")
(if_then_else (eq_attr "mode" "SI")
(const_string "avx512bw")
(const_string "avx512f"))
]
(const_string "*")))
- (set_attr "type" "alu,alu,alu,alu,imovx,msklog")
- (set_attr "length_immediate" "*,*,*,*,0,*")
+ (set_attr "type" "alu,alu,alu,alu,alu,imovx,msklog")
+ (set_attr "length_immediate" "*,*,*,*,*,0,*")
(set (attr "prefix_rex")
(if_then_else
(and (eq_attr "type" "imovx")
(match_operand 1 "ext_QIreg_operand")))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
+ (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
(define_insn "*andqi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
})
(define_insn_and_split "*<code><dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r,&r")
(any_or:<DWI>
- (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
- (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
+ (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,rjO,r")
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r,<di>,o")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, <DWI>mode, operands, TARGET_APX_NDD)"
"#"
DONE;
}
-[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")])
(define_insn "*<code><mode>_1"
- [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k")
+ [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,r,?k")
(any_or:SWI248
- (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k")
- (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,k")))
+ (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,rjM,r,k")
+ (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r,<i>,<m>,k")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
"@
<logic>{<imodesuffix>}\t{%2, %0|%0, %2}
<logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
<logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+ <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
#"
- [(set_attr "isa" "*,*,apx_ndd,apx_ndd,<kmov_isa>")
- (set_attr "type" "alu, alu, alu, alu, msklog")
+ [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>")
+ (set_attr "type" "alu, alu, alu, alu, alu, msklog")
(set_attr "mode" "<MODE>")])
(define_insn_and_split "*notxor<mode>_1"
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*<code>si_1_zext"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+ [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
(zero_extend:DI
- (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
- (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))))
+ (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r")
+ (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT
&& ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
"@
<logic>{l}\t{%2, %k0|%k0, %2}
<logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
+ <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
<logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
[(set_attr "type" "alu")
- (set_attr "isa" "*,apx_ndd,apx_ndd")
+ (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd")
(set_attr "mode" "SI")])
(define_insn "*<code>si_1_zext_imm"
}
return true;
})
+
+;; Return true if OP is a memory operand that can be also used in APX
+;; NDD patterns with immediate operand. With non-default address space,
+;; segment register or address size prefix, APX NDD instruction length
+;; can exceed the 15 byte size limit.
+(define_predicate "apx_ndd_memory_operand"
+ (match_operand 0 "memory_operand")
+{
+ /* OK if immediate operand size < 4 bytes. */
+ if (GET_MODE_SIZE (mode) < 4)
+ return true;
+
+ bool default_addr = ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op));
+ bool address_size_prefix = TARGET_X32 && Pmode == SImode;
+
+ struct ix86_address parts;
+ int ok;
+
+ op = XEXP (op, 0);
+ ok = ix86_decompose_address (op, &parts);
+ gcc_assert (ok);
+
+ if (default_addr)
+ {
+ /* Default address space. */
+
+ /* Not OK with address size prefix, index register and disp. */
+ if (address_size_prefix
+ && parts.index
+ && parts.disp
+ && parts.disp != const0_rtx)
+ return false;
+ }
+ else
+ {
+ /* Non-default address space. */
+
+ /* Not OK without base register. */
+ if (!parts.base)
+ return false;
+
+ /* Not OK with disp and address size prefix. */
+ if (address_size_prefix && parts.disp)
+ return false;
+ }
+
+ return true;
+})
+
+;; Return true if OP is a memory operand which can be used in APX NDD
+;; ADD with register source operand. UNSPEC_GOTNTPOFF memory operand
+;; isn't allowed with APX NDD ADD.
+(define_predicate "apx_ndd_add_memory_operand"
+ (match_operand 0 "memory_operand")
+{
+ op = XEXP (op, 0);
+
+ /* Disallow APX NDD ADD with UNSPEC_GOTNTPOFF. */
+ if (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == UNSPEC
+ && XINT (XEXP (op, 0), 1) == UNSPEC_GOTNTPOFF)
+ return false;
+
+ return true;
+})
--- /dev/null
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-options "-mapxf -O3 -w" } */
+
+long a;
+int b, d, e;
+void
+g (void)
+{
+ int c;
+ _Bool f;
+ __asm__("" : "=c"(c));
+ switch (d)
+ case 2:
+ e = f = c & 2;
+ if (f)
+ a = b;
+}
--- /dev/null
+/* PR target/113711 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapxf -O2" } */
+
+#include <stdint.h>
+
+#define FOO(TYPE, OP_NAME, OP, IMM) \
+TYPE \
+foo_##OP_NAME##_##TYPE (TYPE *p, int64_t off) \
+{ \
+ TYPE b = p[off] OP IMM; \
+ return b; \
+}
+
+FOO (char, add, +, 0x7)
+FOO (short, add, +, 0x2000)
+FOO (int, add, +, 0x2000)
+FOO (int64_t, add, +, 0x2000)
+
+FOO (char, sub, -, 0x7)
+FOO (short, sub, -, 0x2000)
+FOO (int, sub, -, 0x2000)
+FOO (int64_t, sub, -, 0x2000)
+
+FOO (char, and, &, 0x7)
+FOO (short, and, &, 0x2000)
+FOO (int, and, &, 0x2000)
+FOO (int64_t, and, &, 0x2000)
+
+FOO (char, or, |, 0x7)
+FOO (short, or, |, 0x2000)
+FOO (int, or, |, 0x2000)
+FOO (int64_t, or, |, 0x2000)
+
+FOO (char, xor, ^, 0x7)
+FOO (short, xor, ^, 0x2000)
+FOO (int, xor, ^, 0x2000)
+FOO (int64_t, xor, ^, 0x2000)
+
+FOO (char, shl, <<, 0x7)
+FOO (short, shl, <<, 0x7)
+FOO (int, shl, <<, 0x7)
+FOO (int64_t, shl, <<, 0x7)
+
+FOO (char, sar, >>, 0x7)
+FOO (short, sar, >>, 0x7)
+FOO (int, sar, >>, 0x7)
+FOO (int64_t, sar, >>, 0x7)
+
+/* { dg-final { scan-assembler-not "mov"} } */
--- /dev/null
+/* PR target/113711 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapxf -O2" } */
+
+#include <stdint.h>
+
+#define FOO(TYPE, OP_NAME, OP, IMM) \
+extern TYPE foo_##OP_NAME##_##TYPE##_var; \
+TYPE \
+foo_##OP_NAME##_##TYPE (void) \
+{ \
+ TYPE b = foo_##OP_NAME##_##TYPE##_var OP IMM; \
+ return b; \
+}
+
+#define BAR(TYPE, UTYPE, OP_NAME, OP, IMM) \
+extern UTYPE bar_##OP_NAME##_##TYPE##_var; \
+int64_t \
+bar_##OP_NAME##_##TYPE (void) \
+{ \
+ int64_t b = bar_##OP_NAME##_##TYPE##_var OP IMM; \
+ return b; \
+}
+
+FOO (char, add, +, 0x7)
+FOO (short, add, +, 0x2000)
+FOO (int, add, +, 0x2000)
+BAR (int, unsigned int, add, +, 0x2000)
+FOO (int64_t, add, +, 0x2000)
+BAR (int64_t, uint64_t, add, +, 0x2000)
+
+FOO (char, sub, -, 0x7)
+FOO (short, sub, -, 0x2000)
+FOO (int, sub, -, 0x2000)
+BAR (int, unsigned int, sub, -, 0x2000)
+FOO (int64_t, sub, -, 0x2000)
+BAR (int64_t, uint64_t, sub, -, 0x2000)
+
+FOO (char, and, &, 0x7)
+FOO (short, and, &, 0x2000)
+FOO (int, and, &, 0x2000)
+BAR (int, unsigned int, and, &, 0x2000)
+FOO (int64_t, and, &, 0x2000)
+BAR (int64_t, uint64_t, and, &, 0x2000)
+
+FOO (char, or, |, 0x7)
+FOO (short, or, |, 0x2000)
+FOO (int, or, |, 0x2000)
+BAR (int, unsigned int, or, |, 0x2000)
+FOO (int64_t, or, |, 0x2000)
+BAR (int64_t, uint64_t, or, |, 0x2000)
+
+FOO (char, xor, ^, 0x7)
+FOO (short, xor, ^, 0x2000)
+FOO (int, xor, ^, 0x2000)
+BAR (int, unsigned int, xor, ^, 0x2000)
+FOO (int64_t, xor, ^, 0x2000)
+BAR (int64_t, uint64_t, xor, ^, 0x2000)
+
+FOO (char, shl, <<, 0x7)
+FOO (short, shl, <<, 0x7)
+FOO (int, shl, <<, 0x7)
+BAR (int, unsigned int, shl, <<, 0x7)
+FOO (int64_t, shl, <<, 0x7)
+BAR (int64_t, uint64_t, shl, <<, 0x7)
+
+FOO (char, sar, >>, 0x7)
+FOO (short, sar, >>, 0x7)
+FOO (int, sar, >>, 0x7)
+BAR (int, unsigned int, sar, >>, 0x7)
+FOO (int64_t, sar, >>, 0x7)
+BAR (int64_t, uint64_t, sar, >>, 0x7)
+
+/* { dg-final { scan-assembler-not "mov"} } */
--- /dev/null
+/* PR target/113711 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-options "-mapxf -O2" } */
+
+#include <stdint.h>
+
+#define FOO(TYPE, OP_NAME, OP, IMM) \
+TYPE \
+foo_##OP_NAME##_##TYPE (void) \
+{ \
+ TYPE b = (*(TYPE __seg_fs *) 0) OP IMM; \
+ return b; \
+}
+
+#define BAR(TYPE, UTYPE, OP_NAME, OP, IMM) \
+int64_t \
+bar_##OP_NAME##_##TYPE (void) \
+{ \
+ int64_t b = (*(UTYPE __seg_fs *) 0) OP IMM; \
+ return b; \
+}
+
+FOO (char, add, +, 0x7)
+BAR (char, unsigned char, add, +, 0x7)
+FOO (short, add, +, 0x2000)
+BAR (short, unsigned short, add, +, 0x2000)
+FOO (int, add, +, 0x2000)
+BAR (int, unsigned int, add, +, 0x2000)
+FOO (int64_t, add, +, 0x2000)
+BAR (int64_t, uint64_t, add, +, 0x2000)
+FOO (__int128_t, add, +, 0x2000)
+BAR (__int128_t, __uint128_t, add, +, 0x2000)
+
+FOO (char, sub, -, 0x7)
+BAR (char, unsigned char, sub, -, 0x7)
+FOO (short, sub, -, 0x2000)
+BAR (short, unsigned short, sub, -, 0x2000)
+FOO (int, sub, -, 0x2000)
+BAR (int, unsigned int, sub, -, 0x2000)
+FOO (int64_t, sub, -, 0x2000)
+BAR (int64_t, uint64_t, sub, -, 0x2000)
+FOO (__int128_t, sub, -, 0x2000)
+BAR (__int128_t, __uint128_t, sun, -, 0x2000)
+
+FOO (char, and, &, 0x7)
+BAR (char, unsigned char, and, &, 0x7)
+FOO (short, and, &, 0x2000)
+BAR (short, unsigned short, and, &, 0x2000)
+FOO (int, and, &, 0x2000)
+BAR (int, unsigned int, and, &, 0x2000)
+FOO (int64_t, and, &, 0x2000)
+BAR (int64_t, uint64_t, and, &, 0x2000)
+FOO (__int128_t, and, &, 0x2000)
+BAR (__int128_t, __uint128_t, and, &, 0x2000)
+
+FOO (char, or, |, 0x7)
+BAR (char, unsigned char, or, |, 0x7)
+FOO (short, or, |, 0x2000)
+BAR (short, unsigned short, or, |, 0x2000)
+FOO (int, or, |, 0x2000)
+BAR (int, unsigned int, or, |, 0x2000)
+FOO (int64_t, or, |, 0x2000)
+BAR (int64_t, uint64_t, or, |, 0x2000)
+FOO (__int128_t, or, |, 0x2000)
+BAR (__int128_t, __uint128_t, or, |, 0x2000)
+
+FOO (char, xor, ^, 0x7)
+BAR (char, unsigned char, xor, ^, 0x7)
+FOO (short, xor, ^, 0x2000)
+BAR (short, unsigned short, xor, ^, 0x2000)
+FOO (int, xor, ^, 0x2000)
+BAR (int, unsigned int, xor, ^, 0x2000)
+FOO (int64_t, xor, ^, 0x2000)
+BAR (int64_t, uint64_t, xor, ^, 0x2000)
+FOO (__int128_t, xor, ^, 0x2000)
+BAR (__int128_t, __uint128_t, xor, ^, 0x2000)
+
+FOO (char, shl, <<, 0x7)
+BAR (char, unsigned char, shl, <<, 0x7)
+FOO (short, shl, <<, 0x7)
+BAR (short, unsigned short, shl, <<, 0x7)
+FOO (int, shl, <<, 0x7)
+BAR (int, unsigned int, shl, <<, 0x7)
+FOO (int64_t, shl, <<, 0x7)
+BAR (int64_t, uint64_t, shl, <<, 0x7)
+FOO (__int128_t, shl, <<, 0x7)
+BAR (__int128_t, __uint128_t, shl, <<, 0x7)
+
+FOO (char, sar, >>, 0x7)
+BAR (char, unsigned char, sar, >>, 0x7)
+FOO (short, sar, >>, 0x7)
+BAR (short, unsigned short, sar, >>, 0x7)
+FOO (int, sar, >>, 0x7)
+BAR (int, unsigned int, sar, >>, 0x7)
+FOO (int64_t, sar, >>, 0x7)
+BAR (int64_t, uint64_t, sar, >>, 0x7)
+FOO (__int128_t, sar, >>, 0x7)
+BAR (__int128_t, __uint128_t, sar, >>, 0x7)
--- /dev/null
+/* PR target/113711 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapxf -O2" } */
+
+#include <stdint.h>
+
+#define FOO(TYPE, OP_NAME, OP, IMM) \
+TYPE \
+foo_##OP_NAME##_##TYPE (void) \
+{ \
+ TYPE b = (*(TYPE *) 0x20000) OP IMM; \
+ return b; \
+}
+
+#define BAR(TYPE, UTYPE, OP_NAME, OP, IMM) \
+int64_t \
+bar_##OP_NAME##_##TYPE (void) \
+{ \
+ int64_t b = (*(UTYPE *) 0x20000) OP IMM; \
+ return b; \
+}
+
+#define SEG(TYPE, OP_NAME, OP, IMM) \
+TYPE \
+seg_##OP_NAME##_##TYPE (void) \
+{ \
+ TYPE b = (*(TYPE __seg_fs *) 0) OP IMM; \
+ return b; \
+}
+
+FOO (char, add, +, 0x7)
+SEG (char, add, +, 0x7)
+FOO (short, add, +, 0x2000)
+SEG (short, add, +, 0x2000)
+FOO (int, add, +, 0x2000)
+BAR (int, unsigned int, add, +, 0x2000)
+FOO (int64_t, add, +, 0x2000)
+BAR (int64_t, uint64_t, add, +, 0x2000)
+
+FOO (char, sub, -, 0x7)
+SEG (char, sub, -, 0x7)
+FOO (short, sub, -, 0x2000)
+SEG (short, sub, -, 0x2000)
+FOO (int, sub, -, 0x2000)
+BAR (int, unsigned int, sub, -, 0x2000)
+FOO (int64_t, sub, -, 0x2000)
+BAR (int64_t, uint64_t, sub, -, 0x2000)
+
+FOO (char, and, &, 0x7)
+SEG (char, and, &, 0x7)
+FOO (short, and, &, 0x2000)
+SEG (short, and, &, 0x2000)
+FOO (int, and, &, 0x2000)
+BAR (int, unsigned int, and, &, 0x2000)
+FOO (int64_t, and, &, 0x2000)
+BAR (int64_t, uint64_t, and, &, 0x2000)
+
+FOO (char, or, |, 0x7)
+SEG (char, or, |, 0x7)
+FOO (short, or, |, 0x2000)
+SEG (short, or, |, 0x2000)
+FOO (int, or, |, 0x2000)
+BAR (int, unsigned int, or, |, 0x2000)
+FOO (int64_t, or, |, 0x2000)
+BAR (int64_t, uint64_t, or, |, 0x2000)
+
+FOO (char, xor, ^, 0x7)
+SEG (char, xor, ^, 0x7)
+FOO (short, xor, ^, 0x2000)
+SEG (short, xor, ^, 0x2000)
+FOO (int, xor, ^, 0x2000)
+BAR (int, unsigned int, xor, ^, 0x2000)
+FOO (int64_t, xor, ^, 0x2000)
+BAR (int64_t, uint64_t, xor, ^, 0x2000)
+
+FOO (char, shl, <<, 0x7)
+SEG (char, shl, <<, 0x7)
+FOO (short, shl, <<, 0x7)
+SEG (short, shl, <<, 0x7)
+FOO (int, shl, <<, 0x7)
+SEG (int, shl, <<, 0x7)
+BAR (int, unsigned int, shl, <<, 0x7)
+FOO (int64_t, shl, <<, 0x7)
+SEG (int64_t, shl, <<, 0x7)
+BAR (int64_t, uint64_t, shl, <<, 0x7)
+
+FOO (char, sar, >>, 0x7)
+SEG (char, sar, >>, 0x7)
+FOO (short, sar, >>, 0x7)
+SEG (short, sar, >>, 0x7)
+FOO (int, sar, >>, 0x7)
+SEG (int, sar, >>, 0x7)
+BAR (int, unsigned int, sar, >>, 0x7)
+FOO (int64_t, sar, >>, 0x7)
+SEG (int64_t, sar, >>, 0x7)
+BAR (int64_t, uint64_t, sar, >>, 0x7)
+
+/* { dg-final { scan-assembler-not "mov"} } */
--- /dev/null
+/* PR target/113711 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-options "-mapxf -O2" } */
+
+typedef signed __int128 S;
+int o;
+
+S
+qux (void)
+{
+ S z;
+ o = __builtin_add_overflow (*(S __seg_fs *) 0x1000, 0x200, &z);
+ return z;
+}
--- /dev/null
+/* PR target/113711 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-options "-mapxf -O2" } */
+
+unsigned __int128
+foo (void)
+{
+ return *((unsigned __int128 __seg_fs *) 0x1000) + 0x2000;
+}
--- /dev/null
+/* PR target/113711 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-options "-mapxf -O2" } */
+
+#include <stdint.h>
+
+extern int bar __attribute__((__visibility__ ("hidden")));
+
+uintptr_t
+foo (void)
+{
+ return (*(uintptr_t __seg_fs *) 0x1000) - (uintptr_t) &bar;
+}
--- /dev/null
+/* PR target/113733 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-options "-mapxf -O3 -w" } */
+
+extern __thread int a, j;
+enum b
+{
+ c,
+ d
+};
+struct e
+{
+ long f;
+ struct
+ {
+ char g[1024];
+ };
+} typedef h ();
+long i;
+int o (char *);
+static enum b
+k (int *p)
+{
+ h l;
+ struct e n;
+ do
+ {
+ l (n, n.f, p);
+ char **m;
+ for (; *m; ++m)
+ if (o (*m))
+ i = j;
+ }
+ while (d);
+}
+void
+getgrouplist ()
+{
+ k (&a);
+}
--- /dev/null
+/* PR target/113711 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-options "-mapxf -O2" } */
+
+#include <stdint.h>
+
+#define DECL(TYPE) \
+__thread TYPE TYPE##_a = 255; \
+TYPE * volatile TYPE##_a_in_other_thread = (TYPE *)12345;
+
+DECL(uint64_t)
+DECL(uint32_t)
+
+#define FOO(TYPE, name, op, val) \
+void * \
+thread_func##TYPE##name (void *arg) \
+{ \
+ TYPE##_a_in_other_thread = &TYPE##_a; \
+ TYPE##_a = TYPE##_a op val; \
+ *((TYPE *) arg) = TYPE##_a; \
+ return (void *)0; \
+}
+
+FOO(uint64_t, add, +, 0x2000)
+FOO(uint32_t, add, +, 0x2000)
+
+FOO(uint64_t, sub, -, 0x2000)
+FOO(uint32_t, sub, -, 0x2000)
+
+FOO(uint64_t, or, |, 0x2000)
+FOO(uint32_t, or, |, 0x2000)
+
+FOO(uint64_t, and, &, 0x2000)
+FOO(uint32_t, and, &, 0x2000)
+
+FOO(uint64_t, xor, ^, 0x2000)
+FOO(uint32_t, xor, ^, 0x2000)
--- /dev/null
+/* PR target/113711 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-options "-mapxf -O2" } */
+
+typedef signed __int128 S;
+__thread S var;
+int o;
+
+S
+qux (void)
+{
+ S z;
+ o = __builtin_add_overflow (var, 0x200, &z);
+ return z;
+}
--- /dev/null
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-require-effective-target tls } */
+/* { dg-options "-mapxf -O2" } */
+
+#define DECL(TYPE) \
+extern __thread TYPE TYPE##_a;
+
+DECL(__int128_t)
+DECL(__uint128_t)
+
+#define FOO(TYPE, name, op, val) \
+TYPE \
+thread_func##TYPE##name (void) \
+{ \
+ return TYPE##_a op val; \
+}
+
+FOO(__int128_t, add, +, 0x2000)
+FOO(__uint128_t, add, +, 0x2000)
+
+FOO(__int128_t, sub, -, 0x2000)
+FOO(__uint128_t, sub, -, 0x2000)
+
+FOO(__int128_t, or, |, 0x2000)
+FOO(__uint128_t, or, |, 0x2000)
+
+FOO(__int128_t, and, &, 0x2000)
+FOO(__uint128_t, and, &, 0x2000)
+
+FOO(__int128_t, xor, ^, 0x2000)
+FOO(__uint128_t, xor, ^, 0x2000)
--- /dev/null
+/* PR target/113711 */
+/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
+/* { dg-require-effective-target maybe_x32 } */
+/* { dg-options "-mapxf -O2 -mx32" } */
+
+#include <stdint.h>
+
+#define FOO(TYPE, OP_NAME, OP, IMM) \
+TYPE \
+foo_##OP_NAME##_##TYPE (int off, TYPE *ptr) \
+{ \
+ TYPE b = ptr[off + 0x100] + IMM; \
+ return b; \
+}
+
+FOO (char, add, +, 0x7)
+FOO (short, add, +, 0x2000)
+FOO (int, add, +, 0x2000)
+FOO (int64_t, add, +, 0x2000)
+
+FOO (char, sub, -, 0x7)
+FOO (short, sub, -, 0x2000)
+FOO (int, sub, -, 0x2000)
+FOO (int64_t, sub, -, 0x2000)
+
+FOO (char, and, &, 0x7)
+FOO (short, and, &, 0x2000)
+FOO (int, and, &, 0x2000)
+FOO (long, and, &, 0x2000)
+
+FOO (char, or, |, 0x7)
+FOO (short, or, |, 0x2000)
+FOO (int, or, |, 0x2000)
+FOO (int64_t, or, |, 0x2000)
+
+FOO (char, xor, ^, 0x7)
+FOO (short, xor, ^, 0x2000)
+FOO (int, xor, ^, 0x2000)
+FOO (long, xor, ^, 0x2000)
+
+FOO (char, shl, <<, 0x7)
+FOO (short, shl, <<, 0x7)
+FOO (int, shl, <<, 0x7)
+FOO (int64_t, shl, <<, 0x7)
+
+FOO (char, sar, >>, 0x7)
+FOO (short, sar, >>, 0x7)
+FOO (int, sar, >>, 0x7)
+FOO (int64_t, sar, >>, 0x7)