Discussion:
[PATCH] S12Z opcodes: Fix bug disassembling certain shift instructions.
(too old to reply)
John Darrington
2018-11-12 09:15:50 UTC
Permalink
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
John Darrington
2018-11-21 07:25:03 UTC
Permalink
Ping!
On Mon, Nov 12, 2018 at 10:15:50AM +0100, John Darrington wrote:
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
--
Avoid eavesdropping. Send strong encrypted email.
PGP Public key ID: 1024D/2DE827B3
fingerprint = 8797 A26D 0854 2EAB 0285 A290 8A67 719C 2DE8 27B3
See http://sks-keyservers.net or any PGP keyserver for public key.
Nick Clifton
2018-11-21 16:25:01 UTC
Permalink
Hi John,
Post by John Darrington
Ping!
*sigh* :-) Sorry again.
Post by John Darrington
testsuite/gas/s12z/shift.s: Add new test case.
testsuite/gas/s12z/shift.d: Add expected result.
s12z-dis.c (print_insn_shift) [SB_REG_REG_N]: Enter special case
if the postbyte matches the appropriate pattern.
Approved - please apply.

Cheers
Nick

Loading...