]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Handle multiple address register classes
authorUros Bizjak <ubizjak@gmail.com>
Fri, 3 Nov 2023 15:30:06 +0000 (16:30 +0100)
committerUros Bizjak <ubizjak@gmail.com>
Fri, 3 Nov 2023 15:30:06 +0000 (16:30 +0100)
The patch generalizes address register class handling to allow multiple
register classes.  For APX EGPR targets, some instructions do not support
GPR32 registers, so it is necessary to limit address register set to
avoid them.  The same situation happens for instructions with high registers,
where REX registers can not be used in the address, so the existing
infrastructure can be adapted to also handle this case.

The patch is mostly a mechanical rename of "gpr32" attribute to "addr" and
introduces no functional changes, although it fixes a couple of inconsistent
attribute values in passing.

A follow-up patch will use the above infrastructure to limit address register
class to legacy registers for instructions with high registers.

gcc/ChangeLog:

* config/i386/i386.cc (ix86_memory_address_use_extended_reg_class_p):
Rename to ...
(ix86_memory_address_reg_class): ... this.  Generalize address
register class handling to allow multiple address register classes.
Return maximal class for unrecognized instructions.  Improve comments.
(ix86_insn_base_reg_class): Rewrite to handle
multiple address register classes.
(ix86_regno_ok_for_insn_base_p): Ditto.
(ix86_insn_index_reg_class): Ditto.
* config/i386/i386.md: Rename "gpr32" attribute to "addr"
and substitute its values with "0" -> "gpr16", "1" -> "*".
(addr): New attribute to limit allowed address register set.
(gpr32): Remove.
* config/i386/mmx.md: Rename "gpr32" attribute to "addr"
and substitute its values with "0" -> "gpr16", "1" -> "*".
* config/i386/sse.md: Ditto.

gcc/config/i386/i386.cc
gcc/config/i386/i386.md
gcc/config/i386/mmx.md
gcc/config/i386/sse.md

index 0f17f7d025862aff37a09784db6f5c321c529b5e..fdc9362cf5b2d3ba165ba3fcff63ffaea5ceb949 100644 (file)
@@ -11357,93 +11357,116 @@ ix86_validate_address_register (rtx op)
   return NULL_RTX;
 }
 
-/* Return true if insn memory address can use any available reg
-   in BASE_REG_CLASS or INDEX_REG_CLASS, otherwise false.
-   For APX, some instruction can't be encoded with gpr32
-   which is BASE_REG_CLASS or INDEX_REG_CLASS, for that case
-   returns false.  */
-static bool
-ix86_memory_address_use_extended_reg_class_p (rtx_insn* insn)
+/* Determine which memory address register set insn can use.  */
+
+static enum attr_addr
+ix86_memory_address_reg_class (rtx_insn* insn)
 {
-  /* LRA will do some initialization with insn == NULL,
-     return the maximum reg class for that.
-     For other cases, real insn will be passed and checked.  */
-  bool ret = true;
+  /* LRA can do some initialization with NULL insn,
+     return maximum register class in this case.  */
+  enum attr_addr addr_rclass = ADDR_GPR32;
+
   if (TARGET_APX_EGPR && insn)
     {
       if (asm_noperands (PATTERN (insn)) >= 0
          || GET_CODE (PATTERN (insn)) == ASM_INPUT)
-       return ix86_apx_inline_asm_use_gpr32;
+       return ix86_apx_inline_asm_use_gpr32 ? ADDR_GPR32 : ADDR_GPR16;
 
+      /* Return maximum register class for unrecognized instructions.  */
       if (INSN_CODE (insn) < 0)
-       return false;
+       return addr_rclass;
 
-      /* Try recog the insn before calling get_attr_gpr32. Save
-        the current recog_data first.  */
-      /* Also save which_alternative for current recog.  */
+      /* Try to recognize the insn before calling get_attr_addr.
+        Save current recog_data and current alternative.  */
+      struct recog_data_d saved_recog_data = recog_data;
+      int saved_alternative = which_alternative;
 
-      struct recog_data_d recog_data_save = recog_data;
-      int which_alternative_saved = which_alternative;
-
-      /* Update the recog_data for alternative check. */
+      /* Update recog_data for processing of alternatives.  */
       if (recog_data.insn != insn)
        extract_insn_cached (insn);
 
-      /* If alternative is not set, loop throught each alternative
-        of insn and get gpr32 attr for all enabled alternatives.
-        If any enabled alternatives has 0 value for gpr32, disallow
-        gpr32 for addressing.  */
-      if (which_alternative_saved == -1)
+      /* If current alternative is not set, loop throught enabled
+        alternatives and get the most limited register class.  */
+      if (saved_alternative == -1)
        {
          alternative_mask enabled = get_enabled_alternatives (insn);
-         bool curr_insn_gpr32 = false;
+
          for (int i = 0; i < recog_data.n_alternatives; i++)
            {
              if (!TEST_BIT (enabled, i))
                continue;
+
              which_alternative = i;
-             curr_insn_gpr32 = get_attr_gpr32 (insn);
-             if (!curr_insn_gpr32)
-               ret = false;
+             addr_rclass = MIN (addr_rclass, get_attr_addr (insn));
            }
        }
       else
        {
-         which_alternative = which_alternative_saved;
-         ret = get_attr_gpr32 (insn);
+         which_alternative = saved_alternative;
+         addr_rclass = get_attr_addr (insn);
        }
 
-      recog_data = recog_data_save;
-      which_alternative = which_alternative_saved;
+      recog_data = saved_recog_data;
+      which_alternative = saved_alternative;
     }
 
-  return ret;
+  return addr_rclass;
 }
 
-/* For APX, some instructions can't be encoded with gpr32.  */
+/* Return memory address register class insn can use.  */
+
 enum reg_class
 ix86_insn_base_reg_class (rtx_insn* insn)
 {
-  if (ix86_memory_address_use_extended_reg_class_p (insn))
-    return BASE_REG_CLASS;
-  return GENERAL_GPR16;
+  switch (ix86_memory_address_reg_class (insn))
+    {
+    case ADDR_GPR8:
+      gcc_unreachable ();
+    case ADDR_GPR16:
+      return GENERAL_GPR16;
+    case ADDR_GPR32:
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  return BASE_REG_CLASS;
 }
 
 bool
 ix86_regno_ok_for_insn_base_p (int regno, rtx_insn* insn)
 {
+  switch (ix86_memory_address_reg_class (insn))
+    {
+    case ADDR_GPR8:
+      gcc_unreachable ();
+    case ADDR_GPR16:
+      return GENERAL_GPR16_REGNO_P (regno);
+    case ADDR_GPR32:
+      break;
+    default:
+      gcc_unreachable ();
+    }
 
-  if (ix86_memory_address_use_extended_reg_class_p (insn))
-    return GENERAL_REGNO_P (regno);
-  return GENERAL_GPR16_REGNO_P (regno);
+  return GENERAL_REGNO_P (regno);
 }
 
 enum reg_class
 ix86_insn_index_reg_class (rtx_insn* insn)
 {
-  if (ix86_memory_address_use_extended_reg_class_p (insn))
-    return INDEX_REG_CLASS;
-  return INDEX_GPR16;
+  switch (ix86_memory_address_reg_class (insn))
+    {
+    case ADDR_GPR8:
+      gcc_unreachable ();
+    case ADDR_GPR16:
+      return INDEX_GPR16;
+    case ADDR_GPR32:
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  return INDEX_REG_CLASS;
 }
 
 /* Recognizes RTL expressions that are valid memory addresses for an
index 663db73707a5c813db814e0b9eab5d776c8e82b5..ecc74e9994e565b17655b5e7bdd7d7b182330ff2 100644 (file)
 ;; Define attribute to indicate unaligned ssemov insns
 (define_attr "movu" "0,1" (const_string "0"))
 
-;; Define attribute to indicate gpr32 insns.
-(define_attr "gpr32" "0, 1" (const_string "1"))
+;; Define attribute to limit memory address register set.
+(define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
 
 ;; Define instruction set of MMX instructions
 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
                  (const_string "avx")
               ]
               (const_string "*")))
-   (set (attr "gpr32")
+   (set (attr "addr")
        (if_then_else (eq_attr "alternative" "14")
-                     (const_string "0")
-                     (const_string "1")))
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "type")
      (cond [(eq_attr "alternative" "4,5,6,7")
              (const_string "mskmov")
                 (const_string "avx")
              ]
              (const_string "*")))
-   (set (attr "gpr32")
-       (if_then_else (eq_attr "alternative" "8")
-                     (const_string "0")
-                     (const_string "1")))
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "7")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "type")
        (cond [(eq_attr "alternative" "4")
                 (const_string "sselog1")
    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "ssecmp")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex")
    rcpss\t{%1, %d0|%d0, %1}
    vrcpss\t{%1, %d0|%d0, %1}"
   [(set_attr "isa" "*,*,noavx,avx")
-   (set_attr "gpr32" "1,1,1,0")
+   (set_attr "addr" "*,*,*,gpr16")
    (set_attr "type" "sse")
    (set_attr "atom_sse_attr" "rcp")
    (set_attr "btver2_sse_attr" "rcp")
    rsqrtss\t{%1, %d0|%d0, %1}
    vrsqrtss\t{%1, %d0|%d0, %1}"
   [(set_attr "isa" "*,*,noavx,avx")
-   (set_attr "gpr32" "1,1,1,0")
+   (set_attr "addr" "*,*,*,gpr16")
    (set_attr "type" "sse")
    (set_attr "atom_sse_attr" "rcp")
    (set_attr "btver2_sse_attr" "rcp")
   [(set_attr "type" "ssecvt")
    (set_attr "prefix_extra" "1,1,1,*,*")
    (set_attr "length_immediate" "1")
-   (set_attr "gpr32" "1,1,0,1,1")
+   (set_attr "addr" "*,*,gpr16,*,*")
    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
    (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
    (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
   "TARGET_64BIT && TARGET_FXSR"
   "fxsave64\t%0"
   [(set_attr "type" "other")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "memory" "store")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
   "TARGET_64BIT && TARGET_FXSR"
   "fxrstor64\t%0"
   [(set_attr "type" "other")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "memory" "load")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
   "<xsave>\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "store")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
 
   "<xsave>\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "store")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
 
   "<xrstor>\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "load")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
 
   "<xrstor>64\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "load")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
 
index ba81ff72551e4d28e82461d38cec541a0c3d2cbe..50402b5b5440dea1340d637144cf693616a3b825 100644 (file)
                  (const_string "avx")
               ]
               (const_string "*")))
-   (set (attr "gpr32")
+   (set (attr "addr")
        (if_then_else (eq_attr "alternative" "7")
-                     (const_string "0")
-                     (const_string "1")))
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "type")
      (cond [(eq_attr "alternative" "6,7,8")
              (if_then_else (match_test "TARGET_AVX512FP16")
     }
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "*,*,gpr16")
    (set_attr "type" "sselog")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
     }
 }
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix_extra" "1")
    (set_attr "type" "sselog")
    (set_attr "length_immediate" "1")
 }
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sselog")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex")
    pextrw\t{%2, %1, %0|%0, %1, %2}
    vpextrw\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "*,sse2,sse4_noavx,avx")
-   (set_attr "gpr32" "1,1,0,1")
+   (set_attr "addr" "*,*,gpr16,*")
    (set_attr "mmx_isa" "native,*,*,*")
    (set_attr "type" "mmxcvt,sselog1,sselog1,sselog1")
    (set_attr "length_immediate" "1")
    vpextrb\t{%2, %1, %k0|%k0, %1, %2}
    vpextrb\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx,avx")
-   (set_attr "gpr32" "1,0,1,1")
+   (set_attr "addr" "*,gpr16,*,*")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    pshufb\t{%2, %0|%0, %2}
    vpshufb\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,maybe_evex")
    pshufb\t{%2, %0|%0, %2}
    vpshufb\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,maybe_evex")
    #
    #"
   [(set_attr "isa" "*,sse4_noavx,avx,sse2,noavx,*,*,*")
-   (set_attr "gpr32" "1,0,1,1,1,1,1,1")
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "1")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set_attr "mmx_isa" "native,*,*,*,*,native,*,*")
    (set_attr "type" "mmxcvt,ssemov,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
    (set (attr "length_immediate")
     }
 }
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    pextrw\t{%2, %1, %0|%0, %1, %2}
    vpextrw\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "*,sse4_noavx,avx")
-   (set_attr "gpr32" "1,0,1")
+   (set_attr "addr" "*,gpr16,*")
    (set_attr "type" "sselog1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "maybe_vex")
    vpextrb\t{%2, %1, %k0|%k0, %1, %2}
    vpextrb\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx,avx")
-   (set_attr "gpr32" "1,0,1,1")
+   (set_attr "addr" "*,gpr16,*,*")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
index 906212fb4c143b6f008d98439df4ca6adbb958b2..e6a5c7911d5e6e031ecd10514d4b9e69e586d4ff 100644 (file)
   "%vlddqu\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "movu" "1")
    (set (attr "prefix_data16")
      (if_then_else
   "%vrcpps\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "atom_sse_attr" "rcp")
    (set_attr "btver2_sse_attr" "rcp")
    (set_attr "prefix" "maybe_vex")
    vrcpss\t{%1, %2, %0|%0, %2, %k1}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "atom_sse_attr" "rcp")
    (set_attr "btver2_sse_attr" "rcp")
    (set_attr "prefix" "orig,vex")
    vrcpss\t{%1, %2, %0|%0, %2, %1}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "atom_sse_attr" "rcp")
    (set_attr "btver2_sse_attr" "rcp")
    (set_attr "prefix" "orig,vex")
   "%vrsqrtps\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "prefix" "maybe_vex")
    (set_attr "mode" "<MODE>")])
 
    vrsqrtss\t{%1, %2, %0|%0, %2, %k1}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "SF")])
 
    vrsqrtss\t{%1, %2, %0|%0, %2, %1}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "SF")])
 
    vaddsub<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sseadd")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set (attr "atom_unit")
      (if_then_else
        (match_test "<MODE>mode == V2DFmode")
   "TARGET_AVX"
   "vh<plusminus_mnemonic>pd\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "sseadd")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "V4DF")])
 
    haddpd\t{%2, %0|%0, %2}
    vhaddpd\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "sseadd")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "V2DF")])
    vhsubpd\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sseadd")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "V2DF")])
 
   "TARGET_AVX"
   "vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "sseadd")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "V8SF")])
 
    vh<plusminus_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sseadd")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "atom_unit" "complex")
    (set_attr "prefix" "orig,vex")
    (set_attr "prefix_rep" "1,*")
   "TARGET_AVX"
   "vcmp<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "type" "ssecmp")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<MODE>")])
   "TARGET_AVX"
   "vcmp<ssescalarmodesuffix>\t{%3, %2, %1, %0|%0, %1, %<iptr>2, %3}"
   [(set_attr "type" "ssecmp")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<ssescalarmode>")])
    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "ssecmp")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex")
    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "ssecmp")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex")
    cmp%D3<ssescalarmodesuffix>\t{%2, %0|%0, %<iptr>2}
    vcmp%D3<ssescalarmodesuffix>\t{%2, %1, %0|%0, %1, %<iptr>2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "ssecmp")
    (set_attr "length_immediate" "1,*")
    (set_attr "prefix" "orig,vex")
   return "";
 }
   [(set_attr "isa" "noavx,avx_noavx512f,avx512dq,avx512f")
-   (set_attr "gpr32" "1,0,1,1")
+   (set_attr "addr" "*,gpr16,*,*")
    (set_attr "type" "sselog")
    (set_attr "prefix" "orig,maybe_vex,evex,evex")
    (set (attr "mode")
   return "";
 }
   [(set_attr "isa" "noavx,avx_noavx512f,avx512vl,avx512f_512")
-   (set_attr "gpr32" "1,0,1,1")
+   (set_attr "addr" "*,gpr16,*,*")
    (set_attr "type" "sselog")
    (set (attr "prefix_data16")
      (if_then_else
      (if_then_else (eq_attr "alternative" "7,8")
                   (const_string "native")
                   (const_string "*")))
-   (set (attr "gpr32")
+   (set (attr "addr")
      (if_then_else (eq_attr "alternative" "3,4")
-                  (const_string "0")
-                  (const_string "1")))
+                  (const_string "gpr16")
+                  (const_string "*")))
    (set (attr "prefix_data16")
      (if_then_else (eq_attr "alternative" "3,4")
                   (const_string "1")
              (const_string "fmov")
           ]
           (const_string "ssemov")))
-   (set (attr "gpr32")
+   (set (attr "addr")
      (if_then_else (eq_attr "alternative" "8,9")
-                  (const_string "0")
-                  (const_string "1")))
+                  (const_string "gpr16")
+                  (const_string "*")))
    (set (attr "prefix_extra")
      (if_then_else (eq_attr "alternative" "8,9,10")
                   (const_string "1")
 }
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "sselog")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
     }
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
   DONE;
 }
   [(set_attr "isa" "noavx,noavx,avx,noavx,avx")
-   (set_attr "gpr32" "0,0,1,1,1")
+   (set_attr "addr" "gpr16,gpr16,*,*,*")
    (set_attr "type" "sselog,sselog,sselog,*,*")
    (set_attr "prefix_data16" "1,1,1,*,*")
    (set_attr "prefix_extra" "1,1,1,*,*")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "isa" "noavx512vl,avx512vl")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix" "vex,evex")
    (set_attr "mode" "OI")])
 
    }
 }
   [(set_attr "isa" "*,sse4_noavx,avx,noavx,avx")
-   (set_attr "gpr32" "1,0,1,1,1")
+   (set_attr "addr" "*,gpr16,*,*,*")
    (set_attr "type" "sselog1,sselog1,sselog1,sseishft1,sseishft1")
    (set_attr "prefix" "maybe_evex")
    (set_attr "mode" "TI")])
    pmuldq\t{%2, %0|%0, %2}
    vpmuldq\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "sseimul")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,vex")
    pmulld\t{%2, %0|%0, %2}
    vpmulld\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "sseimul")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "<bcst_mask_prefix4>")
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "sseiadd")
    (set_attr "prefix_extra" "1")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "prefix" "orig,orig,vex")
    (set_attr "mode" "TI")])
 
    vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sseiadd")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "TI")])
 
    vp<maxmin_int><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "sseiadd")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "prefix_extra" "1,1,*")
    (set_attr "prefix" "orig,orig,vex")
    (set_attr "mode" "TI")])
    p<maxmin_int>b\t{%2, %0|%0, %2}
    vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sseiadd")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "TI")])
      (if_then_else (eq (const_string "<MODE>mode") (const_string "V4DImode"))
                   (const_string "1")
                   (const_string "*")))
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "OI")])
 
    vpcmpeqq\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssecmp")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,vex")
    (set_attr "mode" "TI")])
    pcmpeq<ssemodesuffix>\t{%2, %0|%0, %2}
    vpcmpeq<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "ssecmp")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "TI")])
    vpcmpgtq\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssecmp")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,vex")
    (set_attr "mode" "TI")])
      (if_then_else (eq (const_string "<MODE>mode") (const_string "V4DImode"))
                   (const_string "1")
                   (const_string "*")))
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "OI")])
 
    pcmpgt<ssemodesuffix>\t{%2, %0|%0, %2}
    vpcmpgt<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "ssecmp")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "TI")])
   return "";
 }
   [(set_attr "isa" "noavx,avx_noavx512f,avx512f,*,*")
-   (set_attr "gpr32" "1,0,1,1,1")
+   (set_attr "addr" "*,gpr16,*,*,*")
    (set_attr "type" "sselog")
    (set (attr "prefix_data16")
      (if_then_else
   return "";
 }
   [(set_attr "isa" "noavx,avx_noavx512f,avx512f")
-   (set_attr "gpr32" "1,0,1")
+   (set_attr "addr" "*,gpr16,*")
    (set_attr "type" "sselog")
    (set (attr "prefix_data16")
      (if_then_else
   return "";
 }
   [(set_attr "isa" "noavx,avx_noavx512f,avx512f")
-   (set_attr "gpr32" "1,0,1")
+   (set_attr "addr" "*,gpr16,*")
    (set_attr "type" "sselog")
    (set (attr "prefix_data16")
      (if_then_else
    vp<logic>\t{%2, %1, %0|%0, %1, %2}
    vp<logic>d\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx_noavx512vl,avx512vl")
-   (set_attr "gpr32" "1,0,1")
+   (set_attr "addr" "*,gpr16,*")
    (set_attr "prefix" "orig,vex,evex")
    (set_attr "prefix_data16" "1,*,*")
    (set_attr "type" "sselog")
 }
   [(set_attr "isa" "noavx,noavx,avx,avx,<pinsr_evex_isa>,<pinsr_evex_isa>,avx2")
    (set_attr "type" "sselog")
-   (set_attr "gpr32" "0,0,1,1,1,1,1")
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "0,1")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "prefix_rex")
      (if_then_else
        (and (not (match_test "TARGET_AVX"))
    pextr<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
    vpextr<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "sse2_noavx,avx,sse4_noavx,avx")
-   (set_attr "gpr32" "1,1,0,1")
+   (set_attr "addr" "*,*,gpr16,*")
    (set_attr "type" "sselog1")
    (set (attr "prefix_extra")
      (if_then_else
 }
   [(set_attr "isa" "noavx,avx,avx512dq,noavx,noavx,avx")
    (set_attr "type" "sselog1,sselog1,sselog1,sseishft1,sseishft1,sseishft1")
-   (set_attr "gpr32" "0,1,1,1,1,1")
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "0")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "prefix_extra")
      (if_then_else (eq_attr "alternative" "0,1")
                   (const_string "1")
              (const_string "imov")
           ]
           (const_string "sselog1")))
-   (set_attr "gpr32" "0,1,1,1,1,1,1,1,1,1")
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "0")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "length_immediate")
      (if_then_else (eq_attr "alternative" "0,1,2,4,5,6")
                   (const_string "1")
              (const_string "mmxmov")
           ]
           (const_string "sselog")))
-   (set (attr "gpr32")
+   (set (attr "addr")
      (if_then_else (eq_attr "alternative" "0,1")
-                  (const_string "0")
-                  (const_string "1")))
+                  (const_string "gpr16")
+                  (const_string "*")))
    (set (attr "prefix_extra")
      (if_then_else (eq_attr "alternative" "0,1,2,3")
                   (const_string "1")
        (eq_attr "alternative" "0,1,2,3,4,5")
        (const_string "sselog")
        (const_string "ssemov")))
-   (set (attr "gpr32")
+   (set (attr "addr")
      (if_then_else (eq_attr "alternative" "0,1")
-                  (const_string "0")
-                  (const_string "1")))
+                  (const_string "gpr16")
+                  (const_string "*")))
    (set (attr "prefix_rex")
      (if_then_else (eq_attr "alternative" "0,1,2,3")
                   (const_string "1")
   "%vldmxcsr\t%0"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "1,0")
+   (set_attr "addr" "*,gpr16")
    (set_attr "atom_sse_attr" "mxcsr")
    (set_attr "prefix" "maybe_vex")
    (set_attr "memory" "load")])
   "%vstmxcsr\t%0"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sse")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "atom_sse_attr" "mxcsr")
    (set_attr "prefix" "maybe_vex")
    (set_attr "memory" "store")])
   "TARGET_AVX2"
   "vph<plusminus_mnemonic>w\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "sseiadd")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "vex")
    (set_attr "mode" "OI")])
    vph<plusminus_mnemonic>w\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sseiadd")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "atom_unit" "complex")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,vex")
   "TARGET_AVX2"
   "vph<plusminus_mnemonic>d\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "sseiadd")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "vex")
    (set_attr "mode" "OI")])
    vph<plusminus_mnemonic>d\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sseiadd")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "atom_unit" "complex")
    (set_attr "prefix_data16" "1,*")
    (set_attr "prefix_extra" "1")
 }
   [(set_attr "mmx_isa" "native,sse_noavx,avx")
    (set_attr "type" "sseiadd")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "atom_unit" "complex")
    (set_attr "prefix_extra" "1")
    (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
    pmaddubsw\t{%2, %0|%0, %2}
    vpmaddubsw\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sseiadd")
    (set_attr "atom_unit" "simul")
    (set_attr "prefix_extra" "1")
    pmulhrsw\t{%2, %0|%0, %2}
    vpmulhrsw\t{%2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sseimul")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,maybe_evex")
    pshufb\t{%2, %0|%0, %2}
    vpshufb\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,maybe_evex")
    vpsign<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
    (set_attr "type" "sselog1")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "<sseinsnmode>")])
     }
 }
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sseishft")
    (set_attr "atom_unit" "sishuf")
    (set_attr "prefix_extra" "1")
 }
   [(set_attr "mmx_isa" "native,sse_noavx,avx")
    (set_attr "type" "sseishft")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "atom_unit" "sishuf")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
   "TARGET_SSSE3"
   "%vpabs<ssemodesuffix>\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "maybe_vex")
    vblend<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
    vblendv<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
   "operands[3] = gen_lowpart (<MODE>mode, operands[3]);"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
 }
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
    vdp<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemul")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
   "TARGET_SSE4_1"
   "%vmovntdqa\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,maybe_evex")
    mpsadbw\t{%3, %2, %0|%0, %2, %3}
    vmpsadbw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16")
    (set_attr "type" "sselog1")
-   (set_attr "gpr32" "0")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,vex")
    packusdw\t{%2, %0|%0, %2}
    vpackusdw\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,<mask_prefix>")
    vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "*,*,1")
    (set_attr "prefix" "orig,orig,vex")
   ""
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "*,*,1")
    (set_attr "prefix" "orig,orig,vex")
    vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,orig,vex")
   return "vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
 }
   [(set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex")
   "TARGET_SSE4_1"
   "%vphminposuw\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,vex")
    pmov<extsuffix>bw\t{%1, %0|%0, %1}
    vpmov<extsuffix>bw\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,maybe_evex")
     }
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")])
+   (set_attr "addr" "gpr16,gpr16,*")])
 
 (define_insn_and_split "*sse4_1_zero_extendv8qiv8hi2_4"
   [(set (match_operand:V16QI 0 "register_operand" "=Yr,*x,Yw")
   operands[1] = lowpart_subreg (V16QImode, operands[1], <ssehalfvecmode>mode);
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")])
+   (set_attr "addr" "gpr16,gpr16,*")])
 
 (define_expand "<insn>v8qiv8hi2"
   [(set (match_operand:V8HI 0 "register_operand")
   "TARGET_SSE4_1 && <mask_avx512vl_condition>"
   "%vpmov<extsuffix>bd\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,maybe_evex")
   "TARGET_SSE4_1 && <mask_avx512vl_condition>"
   "%vpmov<extsuffix>wd\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,maybe_evex")
     }
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")])
+   (set_attr "addr" "gpr16,gpr16,*")])
 
 (define_insn_and_split "*sse4_1_zero_extendv4hiv4si2_4"
   [(set (match_operand:V8HI 0 "register_operand" "=Yr,*x,v")
   operands[1] = lowpart_subreg (V8HImode, operands[1], <ssehalfvecmode>mode);
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")])
+   (set_attr "addr" "gpr16,gpr16,*")])
 
 (define_insn "avx512f_<code>v8qiv8di2<mask_name>"
   [(set (match_operand:V8DI 0 "register_operand" "=v")
   "TARGET_SSE4_1 && <mask_avx512vl_condition>"
   "%vpmov<extsuffix>bq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "maybe_evex")
   "TARGET_SSE4_1 && <mask_avx512vl_condition>"
   "%vpmov<extsuffix>wq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,maybe_evex")
   "TARGET_SSE4_1 && <mask_avx512vl_condition>"
   "%vpmov<extsuffix>dq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")
+   (set_attr "addr" "gpr16,gpr16,*")
    (set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,maybe_evex")
     }
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")])
+   (set_attr "addr" "gpr16,gpr16,*")])
 
 (define_insn_and_split "*sse4_1_zero_extendv2siv2di2_4"
   [(set (match_operand:V4SI 0 "register_operand" "=Yr,*x,v")
   operands[1] = lowpart_subreg (V4SImode, operands[1], V2SImode);
 }
   [(set_attr "isa" "noavx,noavx,avx")
-   (set_attr "gpr32" "0,0,1")])
+   (set_attr "addr" "gpr16,gpr16,*")])
 
 (define_expand "<insn>v2siv2di2"
   [(set (match_operand:V2DI 0 "register_operand")
   "TARGET_AVX"
   "vtest<ssemodesuffix>\t{%1, %0|%0, %1}"
   [(set_attr "type" "ssecomi")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<MODE>")])
   "%vptest\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssecomi")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,vex")
    (set (attr "btver2_decode")
   "%vptest\t{%1, %0|%0, %1}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssecomi")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,orig,vex")
    (set_attr "mode" "TI")])
   "%vround<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,noavx,avx")
    (set_attr "type" "ssecvt")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_data16" "1,1,*")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
 }
   [(set_attr "isa" "noavx,noavx,noavx512f,avx512f")
    (set_attr "type" "ssecvt")
-   (set_attr "gpr32" "0,0,0,1")
+   (set_attr "addr" "gpr16,gpr16,gpr16,*")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_data16" "1,1,*,*")
    (set_attr "prefix_extra" "1")
 }
   [(set_attr "isa" "noavx,noavx,noavx512f,avx512f")
    (set_attr "type" "ssecvt")
-   (set_attr "gpr32" "0,0,0,1")
+   (set_attr "addr" "gpr16,gpr16,gpr16,*")
    (set_attr "length_immediate" "1")
    (set_attr "prefix_data16" "1,1,*,*")
    (set_attr "prefix_extra" "1")
   "TARGET_SSE4_2"
   "%vpcmpestri\t{%5, %3, %1|%1, %3, %5}"
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "maybe_vex")
    (set_attr "length_immediate" "1")
   "TARGET_SSE4_2"
   "%vpcmpestrm\t{%5, %3, %1|%1, %3, %5}"
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "maybe_vex")
    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}
    %vpcmpestri\t{%6, %4, %2|%2, %4, %6}"
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "memory" "none,load,none,load")
   DONE;
 }
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "memory" "none,load")
   "TARGET_SSE4_2"
   "%vpcmpistri\t{%3, %2, %1|%1, %2, %3}"
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "maybe_vex")
   "TARGET_SSE4_2"
   "%vpcmpistrm\t{%3, %2, %1|%1, %2, %3}"
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "maybe_vex")
    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}
    %vpcmpistri\t{%4, %3, %2|%2, %3, %4}"
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "memory" "none,load,none,load")
    vaesenc\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,aes,avx512vl")
    (set_attr "type" "sselog1")
-   (set_attr "gpr32" "0,1,1")
+   (set_attr "addr" "gpr16,*,*")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,vex,evex")
    (set_attr "btver2_decode" "double,double,double")
    vaesenclast\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,aes,avx512vl")
    (set_attr "type" "sselog1")
-   (set_attr "gpr32" "0,1,1")
+   (set_attr "addr" "gpr16,*,*")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,vex,evex")
    (set_attr "btver2_decode" "double,double,double") 
    vaesdec\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,aes,avx512vl")
    (set_attr "type" "sselog1")
-   (set_attr "gpr32" "0,1,1")
+   (set_attr "addr" "gpr16,*,*")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,vex,evex")
    (set_attr "btver2_decode" "double,double,double") 
    vaesdeclast\t{%2, %1, %0|%0, %1, %2}
    vaesdeclast\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,aes,avx512vl")
-   (set_attr "gpr32" "0,1,1")
+   (set_attr "addr" "gpr16,*,*")
    (set_attr "type" "sselog1")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,vex,evex")
   "TARGET_AES"
   "%vaesimc\t{%1, %0|%0, %1}"
   [(set_attr "type" "sselog1")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "maybe_vex")
    (set_attr "mode" "TI")])
   "TARGET_AES"
   "%vaeskeygenassist\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "sselog1")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "maybe_vex")
    vpclmulqdq\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "isa" "noavx,avx,vpclmulqdqvl")
    (set_attr "type" "sselog1")
-   (set_attr "gpr32" "0,1,1")
+   (set_attr "addr" "gpr16,*,*")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex,evex")
    (set_attr "mode" "<sseinsnmode>")])
 
 ;; TODO (APX): vmovaps supports EGPR but not others, could split
-;; pattern to enable gpr32 for this one.
+;; pattern to enable rex2 address for this one.
 (define_insn "avx2_permv2ti"
   [(set (match_operand:V4DI 0 "register_operand" "=x")
        (unspec:V4DI
     return "vperm2i128\t{%3, %2, %1, %0|%0, %1, %2, %3}";
   }
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "OI")])
 
    vinsert<shuffletype>32x4\t{$1, %1, %0, %0|%0, %0, %1, 1}"
   [(set_attr "isa" "noavx512vl,*,*,avx512dq,avx512dq,avx512vl,avx512vl")
    (set_attr "type" "ssemov,sselog1,sselog1,ssemov,sselog1,ssemov,sselog1")
-   (set_attr "gpr32" "0,1,1,1,1,1,1")
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "0")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "0,1,1,0,1,0,1")
    (set_attr "prefix" "vex,vex,vex,evex,evex,evex,evex")
   "TARGET_AVX"
   "vperm2<i128>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex")
   return "vperm2<i128>\t{%3, %2, %1, %0|%0, %1, %2, %3}";
 }
   [(set_attr "type" "sselog")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex")
     return "vinsert<i128>\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}";
 }
   [(set_attr "isa" "noavx512vl,avx512vl")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
     return "vinsert<i128>\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}";
 }
   [(set_attr "isa" "noavx512vl,avx512vl")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
     return "vinsert<i128>\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}";
 }
   [(set_attr "isa" "noavx512vl,avx512vl")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    vinsert%~128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}
    vinserti32x4\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
   [(set_attr "isa" "noavx512vl,avx512vl")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    vinsert%~128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
    vinserti32x4\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
   [(set_attr "isa" "noavx512vl,avx512vl")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    vinserti32x4\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
   [(set_attr "isa" "noavx512vl,avx512vl")
    (set_attr "type" "sselog")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex,evex")
    vinsert%~128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
    vinserti32x4\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
   [(set_attr "isa" "noavx512vl,avx512vl")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "type" "sselog")
    (set_attr "prefix_extra" "1")
    (set_attr "length_immediate" "1")
     return "vmaskmov<ssefltmodesuffix>\t{%1, %2, %0|%0, %2, %1}";
 }
   [(set_attr "type" "sselog1")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "vex")
    (set_attr "btver2_decode" "vector")
     return "vmaskmov<ssefltmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
 }
   [(set_attr "type" "sselog1")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "vex")
    (set_attr "btver2_decode" "vector") 
     }
 }
   [(set_attr "isa" "noavx512f,avx512f,*,*")
-   (set_attr "gpr32" "0,1,1,1")
+   (set_attr "addr" "gpr16,*,*,*")
    (set_attr "type" "sselog,sselog,ssemov,ssemov")
    (set_attr "prefix_extra" "1,1,*,*")
    (set_attr "length_immediate" "1,1,*,*")
   "TARGET_AVX2"
   "%M3v<sseintprefix>gatherd<ssemodesuffix>\t{%1, %7, %0|%0, %7, %1}"
   [(set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
   "TARGET_AVX2"
   "%M2v<sseintprefix>gatherd<ssemodesuffix>\t{%1, %6, %0|%0, %6, %1}"
   [(set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
   "TARGET_AVX2"
   "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %7, %2|%2, %7, %5}"
   [(set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
   return "%M2v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %0|%0, %6, %4}";
 }
   [(set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
   "TARGET_AVX2"
   "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %7, %0|%0, %7, %5}"
   [(set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
   "TARGET_AVX2"
   "%M2v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %0|%0, %6, %4}"
   [(set_attr "type" "ssemov")
-   (set_attr "gpr32" "0")
+   (set_attr "addr" "gpr16")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
    gf2p8affineinvqb\t{%3, %2, %0| %0, %2, %3}
    vgf2p8affineinvqb\t{%3, %2, %1, %0<mask_operand4>| %0<mask_operand4>, %1, %2, %3}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,maybe_evex")
    (set_attr "mode" "<sseinsnmode>")])
    gf2p8affineqb\t{%3, %2, %0| %0, %2, %3}
    vgf2p8affineqb\t{%3, %2, %1, %0<mask_operand4>| %0<mask_operand4>, %1, %2, %3}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,maybe_evex")
    (set_attr "mode" "<sseinsnmode>")])
    gf2p8mulb\t{%2, %0| %0, %2}
    vgf2p8mulb\t{%2, %1, %0<mask_operand3>| %0<mask_operand3>, %1, %2}"
   [(set_attr "isa" "noavx,avx")
-   (set_attr "gpr32" "0,1")
+   (set_attr "addr" "gpr16,*")
    (set_attr "prefix_extra" "1")
    (set_attr "prefix" "orig,maybe_evex")
    (set_attr "mode" "<sseinsnmode>")])