On Tue, Feb 6, 2024 at 11:49 AM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> 1. The only supported TLS code sequence with ADD is
>
>         addq foo@gottpoff(%rip),%reg
>
> Change je constraint to a memory operand in APX NDD ADD pattern with
> register source operand.
>
> 2. The instruction length of APX NDD instructions with immediate operand:
>
> op imm, mem, reg
>
> may exceed the size limit of 15 byes when non-default address space,
> segment register or address size prefix are used.
>
> Add jM constraint which is a memory operand valid for APX NDD instructions
> with immediate operand and add jO constraint which is an offsetable memory
> operand valid for APX NDD instructions with immediate operand.  Update
> APX NDD patterns with jM and jO constraints.
Ok.
>
> gcc/
>
>         PR target/113711
>         PR target/113733
>         * config/i386/constraints.md: List all constraints with j prefix.
>         (j>): Change auto-dec to auto-inc in documentation.
>         (je): Changed to a memory constraint with APX NDD TLS operand
>         check.
>         (jM): New memory constraint for APX NDD instructions.
>         (jO): Likewise.
>         * config/i386/i386-protos.h (x86_poff_operand_p): Removed.
>         * config/i386/i386.cc (x86_poff_operand_p): Likewise.
>         * config/i386/i386.md (*add<dwi>3_doubleword): Use rjO.
>         (*add<mode>_1[SWI48]): Use je and jM.
>         (addsi_1_zext): Use jM.
>         (*addv<dwi>4_doubleword_1[DWI]): Likewise.
>         (*sub<mode>_1[SWI]): Use jM.
>         (@add<mode>3_cc_overflow_1[SWI]): Likewise.
>         (*add<dwi>3_doubleword_cc_overflow_1): Use rjO.
>         (*and<dwi>3_doubleword): Likewise.
>         (*anddi_1): Use jM.
>         (*andsi_1_zext): Likewise.
>         (*and<mode>_1[SWI24]): Likewise.
>         (*<code><dwi>3_doubleword[any_or]: Use rjO
>         (*code<mode>_1[any_or SWI248]): Use jM.
>         (*<code>si_1_zext[zero_extend + any_or]): Likewise.
>         * config/i386/predicates.md (apx_ndd_memory_operand): New.
>         (apx_ndd_add_memory_operand): Likewise.
>
> gcc/testsuite/
>
>         PR target/113711
>         PR target/113733
>         * gcc.target/i386/apx-ndd-2.c: New test.
>         * gcc.target/i386/apx-ndd-base-index-1.c: Likewise.
>         * gcc.target/i386/apx-ndd-no-seg-global-1.c: Likewise.
>         * gcc.target/i386/apx-ndd-seg-1.c: Likewise.
>         * gcc.target/i386/apx-ndd-seg-2.c: Likewise.
>         * gcc.target/i386/apx-ndd-seg-3.c: Likewise.
>         * gcc.target/i386/apx-ndd-seg-4.c: Likewise.
>         * gcc.target/i386/apx-ndd-seg-5.c: Likewise.
>         * gcc.target/i386/apx-ndd-tls-1a.c: Likewise.
>         * gcc.target/i386/apx-ndd-tls-2.c: Likewise.
>         * gcc.target/i386/apx-ndd-tls-3.c: Likewise.
>         * gcc.target/i386/apx-ndd-tls-4.c: Likewise.
>         * gcc.target/i386/apx-ndd-x32-1.c: Likewise.
> ---
>  gcc/config/i386/constraints.md                |  36 ++++-
>  gcc/config/i386/i386-protos.h                 |   1 -
>  gcc/config/i386/i386.cc                       |  25 ----
>  gcc/config/i386/i386.md                       | 129 +++++++++---------
>  gcc/config/i386/predicates.md                 |  65 +++++++++
>  gcc/testsuite/gcc.target/i386/apx-ndd-2.c     |  17 +++
>  .../gcc.target/i386/apx-ndd-base-index-1.c    |  50 +++++++
>  .../gcc.target/i386/apx-ndd-no-seg-global-1.c |  74 ++++++++++
>  gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c |  98 +++++++++++++
>  gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c |  98 +++++++++++++
>  gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c |  14 ++
>  gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c |   9 ++
>  gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c |  13 ++
>  .../gcc.target/i386/apx-ndd-tls-1a.c          |  41 ++++++
>  gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c |  38 ++++++
>  gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c |  16 +++
>  gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c |  31 +++++
>  gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c |  49 +++++++
>  18 files changed, 712 insertions(+), 92 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c
>
> diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
> index 280e4c8e36c..64702d9c0a8 100644
> --- a/gcc/config/i386/constraints.md
> +++ b/gcc/config/i386/constraints.md
> @@ -372,6 +372,24 @@ (define_address_constraint "Ts"
>    "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")
>
> @@ -393,7 +411,7 @@ (define_constraint "j<"
>                  (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")))
> @@ -438,7 +456,15 @@ (define_address_constraint "jb"
>  (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)")))
> diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> index 34b93773b69..46214a63974 100644
> --- a/gcc/config/i386/i386-protos.h
> +++ b/gcc/config/i386/i386-protos.h
> @@ -66,7 +66,6 @@ extern bool x86_extended_QIreg_mentioned_p (rtx_insn *);
>  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);
>
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index b3e7c74846e..706dfe8f5b2 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -23406,31 +23406,6 @@ x86_evex_reg_mentioned_p (rtx operands[], int nops)
>    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
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index a82f2e456fe..d5db538bb6a 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -6290,10 +6290,10 @@ (define_expand "add<mode>3"
>  })
>
>  (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)"
>    "#"
> @@ -6332,7 +6332,7 @@ (define_insn_and_split "*add<dwi>3_doubleword"
>        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")
> @@ -6424,10 +6424,10 @@ (define_insn_and_split 
> "*add<dwi>3_doubleword_concat_zext"
>   "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)"
>  {
> @@ -6462,7 +6462,7 @@ (define_insn "*add<mode>_1"
>                     : "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")
> @@ -6484,10 +6484,10 @@ (define_insn "*add<mode>_1"
>  ;; 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)"
> @@ -6523,7 +6523,7 @@ (define_insn "addsi_1_zext"
>                      : "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")
> @@ -7463,7 +7463,7 @@ (define_insn_and_split "*addv<dwi>4_doubleword_1"
>         (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>
> @@ -7833,18 +7833,19 @@ (define_insn_and_split "*sub<dwi>3_doubleword_zext"
>  [(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>")])
>
> @@ -9370,18 +9371,19 @@ (define_insn "@add<mode>3_cc_overflow_1"
>    [(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>")])
>
> @@ -9501,10 +9503,10 @@ (define_insn_and_split 
> "*add<dwi>3_doubleword_cc_overflow_1"
>    [(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)"
>    "#"
> @@ -9546,7 +9548,7 @@ (define_insn_and_split 
> "*add<dwi>3_doubleword_cc_overflow_1"
>    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
> @@ -11690,10 +11692,10 @@ (define_expand "and<mode>3"
>  })
>
>  (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)"
>    "#"
> @@ -11730,13 +11732,13 @@ (define_insn_and_split "*and<dwi>3_doubleword"
>
>    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)"
> @@ -11747,11 +11749,12 @@ (define_insn "*anddi_1"
>     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")
> @@ -11759,7 +11762,7 @@ (define_insn "*anddi_1"
>                  (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")
> @@ -11814,25 +11817,26 @@ (define_split
>
>  ;; 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)"
>    "@
> @@ -11840,19 +11844,20 @@ (define_insn "*and<mode>_1"
>     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")
> @@ -11860,7 +11865,7 @@ (define_insn "*and<mode>_1"
>                  (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")
> @@ -12677,10 +12682,10 @@ (define_expand "<code><mode>3"
>  })
>
>  (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)"
>    "#"
> @@ -12733,13 +12738,13 @@ (define_insn_and_split "*<code><dwi>3_doubleword"
>
>    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)"
>    "@
> @@ -12747,9 +12752,10 @@ (define_insn "*<code><mode>_1"
>     <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"
> @@ -12864,19 +12870,20 @@ (define_insn_and_split "*xor2andn"
>
>  ;; 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"
> diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
> index 06027a84532..4c1aedd7e70 100644
> --- a/gcc/config/i386/predicates.md
> +++ b/gcc/config/i386/predicates.md
> @@ -2248,3 +2248,68 @@ (define_predicate "aeswidekl_operation"
>      }
>    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;
> +})
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-2.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-2.c
> new file mode 100644
> index 00000000000..3a5272d065e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-2.c
> @@ -0,0 +1,17 @@
> +/* { 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;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c
> new file mode 100644
> index 00000000000..208acd36958
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c
> @@ -0,0 +1,50 @@
> +/* 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"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c
> new file mode 100644
> index 00000000000..d2a4040975a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c
> @@ -0,0 +1,74 @@
> +/* 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"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c
> new file mode 100644
> index 00000000000..d18055a9250
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c
> @@ -0,0 +1,98 @@
> +/* 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)
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c
> new file mode 100644
> index 00000000000..5b164ef79a7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c
> @@ -0,0 +1,98 @@
> +/* 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"} } */
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c
> new file mode 100644
> index 00000000000..e7d9c3ca11a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c
> @@ -0,0 +1,14 @@
> +/* 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;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c
> new file mode 100644
> index 00000000000..a60c4d7d9b6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c
> @@ -0,0 +1,9 @@
> +/* PR target/113711 */
> +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */
> +/* { dg-options "-mapxf -O2" } */
> +
> +unsigned __int128
> +foo (void)
> +{
> +  return *((unsigned __int128 __seg_fs *) 0x1000) + 0x2000;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c
> new file mode 100644
> index 00000000000..9be4e96767c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c
> @@ -0,0 +1,13 @@
> +/* 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;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c
> new file mode 100644
> index 00000000000..5bf57a76ef7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c
> @@ -0,0 +1,41 @@
> +/* 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);
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c
> new file mode 100644
> index 00000000000..db985940a54
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c
> @@ -0,0 +1,38 @@
> +/* 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)
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c
> new file mode 100644
> index 00000000000..e7374b44825
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c
> @@ -0,0 +1,16 @@
> +/* 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;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c
> new file mode 100644
> index 00000000000..f3b2eac6a60
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c
> @@ -0,0 +1,31 @@
> +/* { 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)
> diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c 
> b/gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c
> new file mode 100644
> index 00000000000..4280d400458
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c
> @@ -0,0 +1,49 @@
> +/* 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)
> --
> 2.43.0
>


-- 
BR,
Hongtao

Reply via email to