MIPS16: Simplify extended operand handling
authorMaciej W. Rozycki <macro@imgtec.com>
Fri, 23 Dec 2016 19:40:09 +0000 (19:40 +0000)
committerMaciej W. Rozycki <macro@imgtec.com>
Fri, 23 Dec 2016 19:42:28 +0000 (19:42 +0000)
Simplify extended operand handling and only specially process immediates
which require bit shuffling, using the generic operand insertion and
extraction handlers for the '<' (5-bit shift amount) operand code in
particular.  Require the least significant bit of all extended operand
forms to be (artificially) set to 0 for their special processing to
trigger.

gas/
* config/tc-mips.c (mips16_immed): Limit `mips16_immed_extend'
use to operands whose LSB position is zero.

opcodes/
* mips-dis.c (print_mips16_insn_arg): Simplify processing of
extended operands.
* mips16-opc.c (decode_mips16_operand): Switch the extended
form of the `<' operand type to LSB position 22.

gas/ChangeLog
gas/config/tc-mips.c
opcodes/ChangeLog
opcodes/mips-dis.c
opcodes/mips16-opc.c

index 2d0f4b104ded0a5b94fa7dcdaa34dcfb72d3ea1d..3a05d786e4d7013c9d82be3d62a8643e01cb61c8 100644 (file)
@@ -1,3 +1,8 @@
+2016-12-23  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * config/tc-mips.c (mips16_immed): Limit `mips16_immed_extend'
+       use to operands whose LSB position is zero.
+
 2016-12-23  Maciej W. Rozycki  <macro@imgtec.com>
 
        * config/tc-mips.c (match_mips16_insn): Don't update
index 20e8020bda44a0e1429a8b99b14f088985eb93bb..1e7cddcd8d9a3f8ea5058bbed72eebcb39810e17 100644 (file)
@@ -14023,7 +14023,7 @@ mips16_immed (const char *file, unsigned int line, int type,
                      _("operand value out of range for instruction"));
     }
   uval = ((unsigned int) val >> operand->shift) - operand->bias;
-  if (length == 2)
+  if (length == 2 || operand->root.lsb != 0)
     *insn = mips_insert_operand (&operand->root, *insn, uval);
   else
     *insn |= mips16_immed_extend (uval, operand->root.size);
index 0df963212bb1fac6f06d020c3c072fb4a210d50f..469113f5fe12b9b8ea1fe9aebc7d0ffe9ea3d744 100644 (file)
@@ -1,3 +1,10 @@
+2016-12-23  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * mips-dis.c (print_mips16_insn_arg): Simplify processing of
+       extended operands.
+       * mips16-opc.c (decode_mips16_operand): Switch the extended
+       form of the `<' operand type to LSB position 22.
+
 2016-12-23  Maciej W. Rozycki  <macro@imgtec.com>
 
        * mips16-opc.c (decode_mips16_operand): Replace `0' and `4'
index ade51360d0937e71587186b053f7bc2d6acea2ef..a1152cd721a11cc3b10e017d1c3f407adefa6196 100644 (file)
@@ -1823,6 +1823,7 @@ print_mips16_insn_arg (struct disassemble_info *info,
   const fprintf_ftype infprintf = info->fprintf_func;
   void *is = info->stream;
   const struct mips_operand *operand, *ext_operand;
+  unsigned short ext_size;
   unsigned int uval;
   bfd_vma baseaddr;
 
@@ -1927,29 +1928,26 @@ print_mips16_insn_arg (struct disassemble_info *info,
          info->data_size = 1 << int_op->shift;
        }
 
-      if (operand->size == 26)
-       uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
-      else
+      ext_size = 0;
+      if (use_extend)
        {
-         /* Calculate the full field value.  */
-         uval = mips_extract_operand (operand, (extend << 16) | insn);
-         if (use_extend)
+         ext_operand = decode_mips16_operand (type, TRUE);
+         if (ext_operand != operand)
            {
-             ext_operand = decode_mips16_operand (type, TRUE);
-             if (ext_operand != operand)
-               {
-                 operand = ext_operand;
-                 if (operand->size == 16)
-                   uval = (((extend & 0x1f) << 11) | (extend & 0x7e0)
-                           | (uval & 0x1f));
-                 else if (operand->size == 15)
-                   uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
-                 else
-                   uval = ((((extend >> 6) & 0x1f) | (extend & 0x20))
-                           & ((1U << operand->size) - 1));
-               }
+             ext_size = ext_operand->size;
+             operand = ext_operand;
            }
        }
+      if (operand->size == 26)
+       uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
+      else if (ext_size == 16)
+       uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
+      else if (ext_size == 15)
+       uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
+      else if (ext_size == 6)
+       uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
+      else
+       uval = mips_extract_operand (operand, (extend << 16) | insn);
 
       baseaddr = memaddr + 2;
       if (operand->type == OP_PCREL)
index fb0e0b7c260805cf4e445cf12222b0023a478e64..d102b8cbca92d8868cbaf723505580cb6c2f9f5c 100644 (file)
@@ -77,7 +77,7 @@ decode_mips16_operand (char type, bfd_boolean extended_p)
   if (extended_p)
     switch (type)
       {
-      case '<': UINT (5, 0);
+      case '<': UINT (5, 22);
       case '[': UINT (6, 0);
       case ']': UINT (6, 0);