+2021-03-30  Jan Beulich  <jbeulich@suse.com>
+
+       * config/tc-i386.c (rc_op): Delete.
+       (struct Rounding_Operation): Move ...
+       (struct _i386_insn): ... here. Change field "rounding".
+       (build_evex_prefix): Adjust rounding processing.
+       (swap_2_operands): Likewise.
+       (check_VecOperands): Likewise.
+       (RC_SAE_immediate): Likewise.
+       (optimize_encoding): Adjust check for rounding.
+       (build_modrm_byte): Likewise.
+       (output_imm): Likewise.
+       (md_assemble): Initialize rounding type.
+
 2021-03-30  Jan Beulich  <jbeulich@suse.com>
 
        * config/tc-i386.c (broadcast_op): Delete.
 
 
 static const reg_entry *reg_k0;
 
-/* This struct describes rounding control and SAE in the instruction.  */
-struct RC_Operation
-{
-  enum rc_type
-    {
-      rne = 0,
-      rd,
-      ru,
-      rz,
-      saeonly
-    } type;
-  unsigned int operand;
-};
-
-static struct RC_Operation rc_op;
-
 /* VEX prefix.  */
 typedef struct
 {
     } mask;
 
     /* Rounding control and SAE attributes.  */
-    struct RC_Operation *rounding;
+    struct RC_Operation
+    {
+      enum rc_type
+       {
+         rc_none = -1,
+         rne,
+         rd,
+         ru,
+         rz,
+         saeonly
+       } type;
+
+      unsigned int operand;
+    } rounding;
 
     /* Broadcasting attributes.
 
     i.vex.bytes[3] |= 0x80;
 
   /* Don't always set the broadcast bit if there is no RC.  */
-  if (!i.rounding)
+  if (i.rounding.type == rc_none)
     {
       /* Encode the vector length.  */
       unsigned int vec_length;
       if (i.broadcast.type)
        i.vex.bytes[3] |= 0x10;
     }
+  else if (i.rounding.type != saeonly)
+    i.vex.bytes[3] |= 0x10 | (i.rounding.type << 5);
   else
-    {
-      if (i.rounding->type != saeonly)
-       i.vex.bytes[3] |= 0x10 | (i.rounding->type << 5);
-      else
-       i.vex.bytes[3] |= 0x10 | (evexrcig << 5);
-    }
+    i.vex.bytes[3] |= 0x10 | (evexrcig << 5);
 
   if (i.mask.reg)
     i.vex.bytes[3] |= i.mask.reg->reg_num;
           && !i.types[2].bitfield.xmmword
           && (i.tm.opcode_modifier.vex
               || ((!i.mask.reg || i.mask.zeroing)
-                  && !i.rounding
+                  && i.rounding.type == rc_none
                   && is_evex_encoding (&i.tm)
                   && (i.vec_encoding != vex_encoding_evex
                       || cpu_arch_isa_flags.bitfield.cpuavx512vl
 
   /* Initialize globals.  */
   memset (&i, '\0', sizeof (i));
+  i.rounding.type = rc_none;
   for (j = 0; j < MAX_OPERANDS; j++)
     i.reloc[j] = NO_RELOC;
   memset (disp_expressions, '\0', sizeof (disp_expressions));
       else if (i.broadcast.operand == xchg2)
        i.broadcast.operand = xchg1;
     }
-  if (i.rounding)
+  if (i.rounding.type != rc_none)
     {
-      if (i.rounding->operand == xchg1)
-       i.rounding->operand = xchg2;
-      else if (i.rounding->operand == xchg2)
-       i.rounding->operand = xchg1;
+      if (i.rounding.operand == xchg1)
+       i.rounding.operand = xchg2;
+      else if (i.rounding.operand == xchg2)
+       i.rounding.operand = xchg1;
     }
 }
 
     }
 
   /* Check RC/SAE.  */
-  if (i.rounding)
+  if (i.rounding.type != rc_none)
     {
       if (!t->opcode_modifier.sae
-         || (i.rounding->type != saeonly && !t->opcode_modifier.staticrounding))
+         || (i.rounding.type != saeonly && !t->opcode_modifier.staticrounding))
        {
          i.error = unsupported_rc_sae;
          return 1;
         them is rounding, the rounding operand should be the last
         immediate operand.  */
       if (i.imm_operands > 1
-         && i.rounding->operand != i.imm_operands - 1)
+         && i.rounding.operand != i.imm_operands - 1)
        {
          i.error = rc_sae_operand_not_last_imm;
          return 1;
                          && i.imm_operands == 1
                          && (i.types[0].bitfield.imm8
                              || i.types[i.operands - 1].bitfield.imm8
-                             || i.rounding)));
+                             || i.rounding.type != rc_none)));
          if (i.imm_operands == 2)
            source = 2;
          else
          /* RC/SAE operand could be between DEST and SRC.  That happens
             when one operand is GPR and the other one is XMM/YMM/ZMM
             register.  */
-         if (i.rounding && i.rounding->operand == dest)
+         if (i.rounding.type != rc_none && i.rounding.operand == dest)
            dest++;
 
          if (i.tm.opcode_modifier.vexvvvv == VEXXDS)
   for (n = 0; n < i.operands; n++)
     {
       /* Skip SAE/RC Imm operand in EVEX.  They are already handled.  */
-      if (i.rounding && n == i.rounding->operand)
+      if (i.rounding.type != rc_none && n == i.rounding.operand)
        continue;
 
       if (operand_type_check (i.types[n], imm))
     {
       if (!strncmp (pstr, RC_NamesTable[j].name, RC_NamesTable[j].len))
        {
-         if (!i.rounding)
-           {
-             rc_op.type = RC_NamesTable[j].type;
-             rc_op.operand = this_operand;
-             i.rounding = &rc_op;
-           }
-         else
+         if (i.rounding.type != rc_none)
            {
              as_bad (_("duplicated `%s'"), imm_start);
              return 0;
            }
+
+         i.rounding.type = RC_NamesTable[j].type;
+         i.rounding.operand = this_operand;
+
          pstr += RC_NamesTable[j].len;
          match_found = 1;
          break;