Fix the encoding of the MSP430's RRUX instruction.
authorNick Clifton <nickc@redhat.com>
Thu, 4 Feb 2016 09:55:10 +0000 (09:55 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 4 Feb 2016 09:55:10 +0000 (09:55 +0000)
PR target/19561
opcdoe * msp430-dis.c (print_insn_msp430): Add a special case for
decoding an RRC instruction with the ZC bit set in the extension
word.

include * opcode/msp430.h (IGNORE_CARRY_BIT): New define.
(RRUX): Synthesise using case 2 rather than 7.

gas * config/tc-msp430.c (msp430_operands): Remove case 7.  Use case 2
to handle encoding of RRUX instruction.
* testsuite/gas/msp430/msp430x.s: Add more tests of the extended
shift instructions.
* testsuite/gas/msp430/msp430x.d: Update expected disassembly.

gas/ChangeLog
gas/config/tc-msp430.c
gas/testsuite/gas/msp430/msp430x.d
gas/testsuite/gas/msp430/msp430x.s
include/ChangeLog
include/opcode/msp430.h
opcodes/ChangeLog
opcodes/msp430-dis.c

index e147013..e64617c 100644 (file)
@@ -1,12 +1,19 @@
+2016-02-04  Nick Clifton  <nickc@redhat.com>
+
+       PR target/19561
+       * config/tc-msp430.c (msp430_operands): Remove case 7.  Use case 2
+       to handle encoding of RRUX instruction.
+       * testsuite/gas/msp430/msp430x.s: Add more tests of the extended
+       shift instructions.
+       * testsuite/gas/msp430/msp430x.d: Update expected disassembly.
+
 2016-02-03  Max Filippov  <jcmvbkbc@gmail.com>
 
        * config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF*
        substitutions for BFD_RELOC_* as unsigned.
-       * gas/testsuite/gas/xtensa/all.exp: Add loc to list of xtensa
-       tests.
-       * gas/testsuite/gas/xtensa/loc.d: New file: loc test result
-       patterns.
-       * gas/testsuite/gas/xtensa/loc.s: New file: loc test.
+       * testsuite/gas/xtensa/all.exp: Add loc to list of xtensa tests.
+       * testsuite/gas/xtensa/loc.d: New file: loc test result patterns.
+       * testsuite/gas/xtensa/loc.s: New file: loc test.
 
 2016-02-03  Kevin Buettner  <kevinb@redhat.com>
 
index 23b9e77..7e340c3 100644 (file)
@@ -3172,63 +3172,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
            break;
          }
 
-       case 7:
-         {
-           int reg;
-
-           /* RRUX: Synthetic unsigned right shift of a register by one bit.  */
-           if (extended & 0xff)
-             {
-               as_bad (_("repeat count cannot be used with %s"), opcode->name);
-               break;
-             }
-
-           line = extract_operand (line, l1, sizeof (l1));
-           if ((reg = check_reg (l1)) == -1)
-             {
-               as_bad (_("expected register as argument of %s"),
-                       opcode->name);
-               break;
-             }
-
-           if (target_is_430xv2 () && reg == 0)
-             {
-               as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
-               break;
-             }
-
-           if (byte_op)
-             {
-               /* Tricky - there is no single instruction that will do this.
-                  Encode as: RRA.B rN { BIC.B #0x80, rN  */
-               op_length = 6;
-               frag = frag_more (op_length);
-               where = frag - frag_now->fr_literal;
-               bin = 0x1140 | reg;
-               bfd_putl16 ((bfd_vma) bin, frag);
-               dwarf2_emit_insn (2);
-               bin = 0xc070 | reg;
-               bfd_putl16 ((bfd_vma) bin, frag + 2);
-               bin = 0x0080;
-               bfd_putl16 ((bfd_vma) bin, frag + 4);
-               dwarf2_emit_insn (4);
-             }
-           else
-             {
-               /* Encode as RRUM[.A] rN.  */
-               bin = opcode->bin_opcode;
-               if (! addr_op)
-                 bin |= 0x10;
-               bin |= reg;
-               op_length = 2;
-               frag = frag_more (op_length);
-               where = frag - frag_now->fr_literal;
-               bfd_putl16 ((bfd_vma) bin, frag);
-               dwarf2_emit_insn (op_length);
-             }
-           break;
-         }
-
        case 8:
          {
            bfd_boolean need_reloc = FALSE;
@@ -3660,6 +3603,9 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
          else if (! addr_op)
            extended |= BYTE_OPERATION;
 
+         if (is_opcode ("rrux"))
+           extended |= IGNORE_CARRY_BIT;
+         
          if (op1.ol != 0 && ((extended & 0xf) != 0))
            {
              as_bad (_("repeat instruction used with non-register mode instruction"));
index 6bd6db3..8eea453 100644 (file)
@@ -201,27 +201,32 @@ Disassembly of section .text:
 0+039e <[^>]*> 54 0b           rrum    #3,     r4      ;
 0+03a0 <[^>]*> 44 07           rrum.a  #2,     r4      ;
 0+03a2 <[^>]*> 54 03           rrum    #1,     r4      ;
-0+03a4 <[^>]*> 54 03           rrum    #1,     r4      ;
-0+03a6 <[^>]*> 47 03           rrum.a  #1,     r7      ;
-0+03a8 <[^>]*> 45 11           rra.b   r5              ;
-0+03aa <[^>]*> 75 c0 80 00     bic.b   #128,   r5      ;#0x0080
-0+03ae <[^>]*> 56 03           rrum    #1,     r6      ;
-0+03b0 <[^>]*> 40 18 81 10     swpbx.w r1              ;
-0+03b4 <[^>]*> 00 18 90 10 00 00       swpbx.a 0x0000          ;PC rel. 0x03b8
-0+03ba <[^>]*> 40 18 8c 10     swpbx.w r12             ;
-0+03be <[^>]*> 40 18 82 11     sxtx.w  r2              ;
-0+03c2 <[^>]*> 00 18 92 11 00 00       sxtx.a  &0x0000         ;
-0+03c8 <[^>]*> 40 18 82 11     sxtx.w  r2              ;
-0+03cc <[^>]*> 04 18 45 11     rpt #5 \{ rrax.a        r5              ;
-0+03d0 <[^>]*> 85 18 45 11     rpt r5 \{ rrax.a        r5              ;
-0+03d4 <[^>]*> e2 01           adda    r1,     r2      ;
-0+03d6 <[^>]*> c0 01           mova    r1,     r0      ;
-0+03d8 <[^>]*> 41 13           calla   r1              ;
-0+03da <[^>]*> 40 18 01 43     clrx.w  r1              ;
-0+03de <[^>]*> d2 01           cmpa    r1,     r2      ;
-0+03e0 <[^>]*> 40 18 21 83     decdx.w r1              ;
-0+03e4 <[^>]*> 40 18 21 53     incdx.w r1              ;
-0+03e8 <[^>]*> c2 01           mova    r1,     r2      ;
-0+03ea <[^>]*> 10 01           reta                    ;
-0+03ec <[^>]*> f2 01           suba    r1,     r2      ;
-0+03ee <[^>]*> 40 18 80 93 00 00       cmpx.w  #0,     0x00000 ;r3 As==00, PC rel. 0x003f2
+0+03a4 <[^>]*> 40 19 04 10     rrux.w  r4              ;
+0+03a8 <[^>]*> 00 19 47 10     rrux.a  r7              ;
+0+03ac <[^>]*> 40 19 45 10     rrux.b  r5              ;
+0+03b0 <[^>]*> 40 19 06 10     rrux.w  r6              ;
+0+03b4 <[^>]*> 40 18 81 10     swpbx.w r1              ;
+0+03b8 <[^>]*> 00 18 90 10 00 00       swpbx.a 0x0000          ;PC rel. 0x03bc
+0+03be <[^>]*> 40 18 8c 10     swpbx.w r12             ;
+0+03c2 <[^>]*> 40 18 82 11     sxtx.w  r2              ;
+0+03c6 <[^>]*> 00 18 92 11 00 00       sxtx.a  &0x0000         ;
+0+03cc <[^>]*> 40 18 82 11     sxtx.w  r2              ;
+0+03d0 <[^>]*> 04 18 45 11     rpt #5 \{ rrax.a        r5              ;
+0+03d4 <[^>]*> 85 18 45 11     rpt r5 \{ rrax.a        r5              ;
+0+03d8 <[^>]*> e2 01           adda    r1,     r2      ;
+0+03da <[^>]*> c0 01           mova    r1,     r0      ;
+0+03dc <[^>]*> 41 13           calla   r1              ;
+0+03de <[^>]*> 40 18 01 43     clrx.w  r1              ;
+0+03e2 <[^>]*> d2 01           cmpa    r1,     r2      ;
+0+03e4 <[^>]*> 40 18 21 83     decdx.w r1              ;
+0+03e8 <[^>]*> 40 18 21 53     incdx.w r1              ;
+0+03ec <[^>]*> c2 01           mova    r1,     r2      ;
+0+03ee <[^>]*> 10 01           reta                    ;
+0+03f0 <[^>]*> f2 01           suba    r1,     r2      ;
+0+03f2 <[^>]*> 40 18 80 93 00 00       cmpx.w  #0,     0x00000 ;r3 As==00, PC rel. 0x003f6
+0+03f8 <[^>]*> c1 19 01 10     rpt r1 \{ rrux.w        r1              ;
+0+03fc <[^>]*> 41 18 02 10     rpt #2 \{ rrcx.w        r2              ;
+0+0400 <[^>]*> 42 18 47 11     rpt #3 \{ rrax.b        r7              ;
+0+0404 <[^>]*> 84 18 44 11     rpt r4 \{ rrax.a        r4              ;
+0+0408 <[^>]*> 44 18 45 55     rpt #5 \{ rlax.b        r5              ;
+0+040c <[^>]*> 05 18 46 66     rpt #6 \{ rlcx.a        r6              ;
index d968fae..8fef882 100644 (file)
@@ -274,4 +274,10 @@ foo:
        sub.a   r1, r2
        tst.a   fooz
        
-       
+       ;; Check that repeat counts can be used with shift instructions.
+       rpt r1 { rrux.w r1
+       rpt #2 { rrcx.w r2
+       rpt #3 { rrax.b r7
+       rpt r4 { rrax.a r4
+       rpt #5 { rlax.b r5
+       rpt #6 { rlcx.a r6
index cbd40b2..b637fc9 100644 (file)
@@ -1,3 +1,9 @@
+2016-02-04  Nick Clifton  <nickc@redhat.com>
+
+       PR target/19561
+       * opcode/msp430.h (IGNORE_CARRY_BIT): New define.
+       (RRUX): Synthesise using case 2 rather than 7.
+
 2016-01-19  John Baldwin  <jhb@FreeBSD.org>
 
        * elf/common.h (NT_FREEBSD_THRMISC): Define.
index 110d7cf..463e5e6 100644 (file)
@@ -35,7 +35,13 @@ struct msp430_operand_s
 #endif
 };
 
-#define BYTE_OPERATION  (1 << 6)  /* Byte operation flag for all instructions.  */
+/* Byte operation flag for all instructions.  Also used as the
+   A/L bit in the extension word to indicate a 20-bit operation.  */
+#define BYTE_OPERATION    (1 << 6)
+/* Z/C bit in the extension word.  If set the carry bit is ignored
+   for the duration of the operation, although it may be changed as
+   a result of the operation.  */
+#define IGNORE_CARRY_BIT  (1 << 8)  
 
 struct  msp430_opcode_s
 {
@@ -46,7 +52,7 @@ struct  msp430_opcode_s
   int bin_mask;
 };
 
-#define MSP_INSN(name, size, numb, bin, mask) { #name, size, numb, bin, mask }
+#define MSP_INSN(name, fmt, numb, bin, mask) { #name, fmt, numb, bin, mask }
 
 static struct msp430_opcode_s msp430_opcodes[] = 
 {
@@ -156,7 +162,8 @@ static struct msp430_opcode_s msp430_opcodes[] =
 
   MSP_INSN (pushx, -3, 1, 0x1200, 0xff80),
   MSP_INSN (rrax,  -3, 1, 0x1100, 0xff80),
-  MSP_INSN (rrcx,  -3, 1, 0x1000, 0xff80),
+  MSP_INSN (rrcx,  -3, 1, 0x1000, 0xff80), /* Synthesised as RRC but with the Z/C bit clear.  */
+  MSP_INSN (rrux,  -3, 1, 0x1000, 0xff80), /* Synthesised as RRC but with the Z/C bit set.  */
   MSP_INSN (swpbx, -3, 1, 0x1080, 0xffc0),
   MSP_INSN (sxtx,  -3, 1, 0x1180, 0xffc0),
 
@@ -173,8 +180,6 @@ static struct msp430_opcode_s msp430_opcodes[] =
   MSP_INSN (rlam,  -1, 6, 0x0240, 0xf3e0),
   MSP_INSN (rrum,  -1, 6, 0x0340, 0xf3e0),
 
-  MSP_INSN (rrux,  -1, 7, 0x0340, 0xffe0), /* Synthesized in terms of RRUM.  */
-
   MSP_INSN (adda,  -1, 8, 0x00a0, 0xf0b0),
   MSP_INSN (cmpa,  -1, 8, 0x0090, 0xf0b0),
   MSP_INSN (suba,  -1, 8, 0x00b0, 0xf0b0),
index 83cbe6f..f706739 100644 (file)
@@ -1,3 +1,10 @@
+2016-02-04  Nick Clifton  <nickc@redhat.com>
+
+       PR target/19561
+       * msp430-dis.c (print_insn_msp430): Add a special case for
+       decoding an RRC instruction with the ZC bit set in the extension
+       word.
+
 2016-02-02  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * cgen-ibld.in (insert_normal): Rework calculation of shift.
index d7e8d8a..676a2d8 100644 (file)
@@ -1102,7 +1102,7 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
                }
              else if (extension_word)
                {
-                 if (extension_word & (1 << 6))
+                 if (extension_word & BYTE_OPERATION)
                    bc = ".w";
                  else
                    {
@@ -1181,7 +1181,12 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
        prin (stream, "rpt #%d { ", (extension_word & 0xf) + 1);
     }
 
-  if (extension_word && opcode->name[strlen (opcode->name) - 1] != 'x')
+  /* Special case:  RRC with an extension word and the ZC bit set is actually RRU.  */
+  if (extension_word
+      && (extension_word & IGNORE_CARRY_BIT)
+      && strcmp (opcode->name, "rrc") == 0)
+    (*prin) (stream, "rrux%s", bc);
+  else if (extension_word && opcode->name[strlen (opcode->name) - 1] != 'x')
     (*prin) (stream, "%sx%s", opcode->name, bc);
   else
     (*prin) (stream, "%s%s", opcode->name, bc);