[PATCH] S12Z opcodes: Fix bug disassembling certain shift instructions.

John Darrington john@darrington.wattle.id.au
Mon Nov 12 09:16:00 GMT 2018


Shift and rotate instructions when the number of bit positions
was an immediate value greater than 1 were incorrectly disassembled.
This change fixes that problem and extends the test to check for
it.

gas/ChangeLog:

  testsuite/gas/s12z/shift.s: Add new test case.
  testsuite/gas/s12z/shift.d: Add expected result.

opcodes/ChangeLog:

  s12z-dis.c (print_insn_shift) [SB_REG_REG_N]: Enter special case
  if the postbyte matches the appropriate pattern.
---
 gas/testsuite/gas/s12z/shift.d |  3 ++-
 gas/testsuite/gas/s12z/shift.s |  1 +
 opcodes/s12z-dis.c             | 44 ++++++++++++++++++++++++------------------
 3 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/gas/testsuite/gas/s12z/shift.d b/gas/testsuite/gas/s12z/shift.d
index c3244c4bbe..243481b8c4 100644
--- a/gas/testsuite/gas/s12z/shift.d
+++ b/gas/testsuite/gas/s12z/shift.d
@@ -1,5 +1,5 @@
 #objdump: -d
-#name:    
+#name:    Tests for shift and rotate instructions
 #source:  shift.s
 
 
@@ -20,3 +20,4 @@ Disassembly of section .text:
   17:	10 3e 8e    	lsr.p \(d6,x\), #2
   1a:	10 f4 bf    	asl d7, #1
   1d:	10 bc bd    	asr d1, #2
+  20:	16 de 78    	asl d6, d6, #17
diff --git a/gas/testsuite/gas/s12z/shift.s b/gas/testsuite/gas/s12z/shift.s
index cb41f3c030..5fd1468d60 100644
--- a/gas/testsuite/gas/s12z/shift.s
+++ b/gas/testsuite/gas/s12z/shift.s
@@ -9,3 +9,4 @@
 	lsr.p (d6,x), #2
 	asl   d7, #1
 	asr   d1, #2
+	asl   d6, d6, #17
diff --git a/opcodes/s12z-dis.c b/opcodes/s12z-dis.c
index ad39e05217..719f172bcc 100644
--- a/opcodes/s12z-dis.c
+++ b/opcodes/s12z-dis.c
@@ -2363,25 +2363,31 @@ print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte)
       break;
 
     case SB_REG_REG_N:
-      if (sb & 0x08)
-	{
-	  operand_separator (info);
-	  if (byte & 0x10)
-	    {
-	      uint8_t xb;
-	      read_memory (memaddr + 1, &xb, 1, info);
-	      int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
-	      (*info->fprintf_func) (info->stream, "#%d", shift);
-	    }
-	  else
-	    {
-	      (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__);
-	    }
-	}
-      else
-	{
-	  opr_decode (memaddr + 1, info);
-	}
+      {
+        uint8_t xb;
+        read_memory (memaddr + 1, &xb, 1, info);
+        /* This case is slightly unusual.
+           If XB matches the binary pattern 0111XXXX, then instead of
+           interpreting this as a general OPR postbyte in the IMMe4 mode,
+           the XB byte is interpreted in s special way.  */
+        if ((xb & 0xF0) == 0x70)
+          {
+            operand_separator (info);
+            if (byte & 0x10)
+              {
+                int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
+                (*info->fprintf_func) (info->stream, "#%d", shift);
+              }
+            else
+              {
+                (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__);
+              }
+          }
+        else
+          {
+            opr_decode (memaddr + 1, info);
+          }
+      }
       break;
     case SB_REG_OPR_OPR:
       {
-- 
2.11.0



More information about the Binutils mailing list