This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/binutils-2_28-branch] MIPS16: Simplify extended operand handling


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5d766ae78a9dd4e71d7c989e8f3bdf1fd61b8068

commit 5d766ae78a9dd4e71d7c989e8f3bdf1fd61b8068
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Fri Dec 23 19:40:09 2016 +0000

    MIPS16: Simplify extended operand handling
    
    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.
    
    (cherry picked from commit bdd152861ce75c36828904cf3d10f8ce14da6cf5)

Diff:
---
 gas/ChangeLog        |  5 +++++
 gas/config/tc-mips.c |  2 +-
 opcodes/ChangeLog    |  7 +++++++
 opcodes/mips-dis.c   | 36 +++++++++++++++++-------------------
 opcodes/mips16-opc.c |  2 +-
 5 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 2d0f4b1..3a05d78 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,10 @@
 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
 	`forced_insn_length' or the instruction opcode if an operand
 	requires an extended instruction form, but an unextended one
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 20e8020..1e7cddc 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -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);
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 0df9632..469113f 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,12 @@
 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'
 	operand codes with `.' and `F' respectively.
 	(mips16_opcodes): Likewise.
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index ade5136..a1152cd 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -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)
diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c
index fb0e0b7..d102b8c 100644
--- a/opcodes/mips16-opc.c
+++ b/opcodes/mips16-opc.c
@@ -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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]