]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[APX NDD] Disable seg_prefixed memory usage for NDD add
authorHongyu Wang <hongyu.wang@intel.com>
Mon, 13 Nov 2023 10:49:07 +0000 (18:49 +0800)
committerHongyu Wang <hongyu.wang@intel.com>
Thu, 7 Dec 2023 01:31:13 +0000 (09:31 +0800)
NDD uses evex prefix, so when segment prefix is also applied, the instruction
could excceed its 15byte limit, especially adding immediates. This could happen
when "e" constraint accepts any UNSPEC_TPOFF/UNSPEC_NTPOFF constant and it will
add the offset to segment register, which will be encoded using segment prefix.
Disable those *POFF constant usage in NDD add alternatives with new constraint.

gcc/ChangeLog:

* config/i386/constraints.md (je): New constraint.
* config/i386/i386-protos.h (x86_poff_operand_p): New function to
check any *POFF constant in operand.
* config/i386/i386.cc (x86_poff_operand_p): New prototype.
* config/i386/i386.md (*add<mode>_1): Split out je alternative for add.

gcc/config/i386/constraints.md
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.cc
gcc/config/i386/i386.md

index cbee31fa40a0e5876934cffb0dd20d006ba753f1..f4c3c3dd9522de9449e73b2874f135435a0c53fd 100644 (file)
 
 (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)")))
index a9d0c568bba10471654b1d1ce4d2a99ce9b5d5c9..7dfeb6af2252ea9cfcdb30778d592a5a32c2976f 100644 (file)
@@ -66,6 +66,7 @@ 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);
 
index 7c5cab4e2c6b6fb9d56a13b006ef7ed2d9c24303..8aa33aef7e17f79dd8376752e427353528753b65 100644 (file)
@@ -23331,6 +23331,31 @@ 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
index 1e8461833478a17fc435035527ac50e7a4439a1e..a16261212278eee5ccef6b8ee71fe61552a93c5e 100644 (file)
  "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")
+  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r,r")
        (plus:SWI48
-         (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rm,r")
-         (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,re,BM")))
+         (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")))
    (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")
+  [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd")
    (set (attr "type")
      (cond [(eq_attr "alternative" "3")
               (const_string "lea")