Fix the encoding of the MSP430's RRUX instruction.
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.
This commit is contained in:
parent
1b18aa1e79
commit
c1d9289fef
8 changed files with 81 additions and 94 deletions
|
@ -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>
|
2016-02-03 Max Filippov <jcmvbkbc@gmail.com>
|
||||||
|
|
||||||
* config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF*
|
* config/tc-xtensa.c (md_apply_fix): Mark BFD_RELOC_XTENSA_DIFF*
|
||||||
substitutions for BFD_RELOC_* as unsigned.
|
substitutions for BFD_RELOC_* as unsigned.
|
||||||
* gas/testsuite/gas/xtensa/all.exp: Add loc to list of xtensa
|
* testsuite/gas/xtensa/all.exp: Add loc to list of xtensa tests.
|
||||||
tests.
|
* testsuite/gas/xtensa/loc.d: New file: loc test result patterns.
|
||||||
* gas/testsuite/gas/xtensa/loc.d: New file: loc test result
|
* testsuite/gas/xtensa/loc.s: New file: loc test.
|
||||||
patterns.
|
|
||||||
* gas/testsuite/gas/xtensa/loc.s: New file: loc test.
|
|
||||||
|
|
||||||
2016-02-03 Kevin Buettner <kevinb@redhat.com>
|
2016-02-03 Kevin Buettner <kevinb@redhat.com>
|
||||||
|
|
||||||
|
|
|
@ -3172,63 +3172,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
|
||||||
break;
|
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:
|
case 8:
|
||||||
{
|
{
|
||||||
bfd_boolean need_reloc = FALSE;
|
bfd_boolean need_reloc = FALSE;
|
||||||
|
@ -3660,6 +3603,9 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
|
||||||
else if (! addr_op)
|
else if (! addr_op)
|
||||||
extended |= BYTE_OPERATION;
|
extended |= BYTE_OPERATION;
|
||||||
|
|
||||||
|
if (is_opcode ("rrux"))
|
||||||
|
extended |= IGNORE_CARRY_BIT;
|
||||||
|
|
||||||
if (op1.ol != 0 && ((extended & 0xf) != 0))
|
if (op1.ol != 0 && ((extended & 0xf) != 0))
|
||||||
{
|
{
|
||||||
as_bad (_("repeat instruction used with non-register mode instruction"));
|
as_bad (_("repeat instruction used with non-register mode instruction"));
|
||||||
|
|
|
@ -201,27 +201,32 @@ Disassembly of section .text:
|
||||||
0+039e <[^>]*> 54 0b rrum #3, r4 ;
|
0+039e <[^>]*> 54 0b rrum #3, r4 ;
|
||||||
0+03a0 <[^>]*> 44 07 rrum.a #2, r4 ;
|
0+03a0 <[^>]*> 44 07 rrum.a #2, r4 ;
|
||||||
0+03a2 <[^>]*> 54 03 rrum #1, r4 ;
|
0+03a2 <[^>]*> 54 03 rrum #1, r4 ;
|
||||||
0+03a4 <[^>]*> 54 03 rrum #1, r4 ;
|
0+03a4 <[^>]*> 40 19 04 10 rrux.w r4 ;
|
||||||
0+03a6 <[^>]*> 47 03 rrum.a #1, r7 ;
|
0+03a8 <[^>]*> 00 19 47 10 rrux.a r7 ;
|
||||||
0+03a8 <[^>]*> 45 11 rra.b r5 ;
|
0+03ac <[^>]*> 40 19 45 10 rrux.b r5 ;
|
||||||
0+03aa <[^>]*> 75 c0 80 00 bic.b #128, r5 ;#0x0080
|
0+03b0 <[^>]*> 40 19 06 10 rrux.w r6 ;
|
||||||
0+03ae <[^>]*> 56 03 rrum #1, r6 ;
|
0+03b4 <[^>]*> 40 18 81 10 swpbx.w r1 ;
|
||||||
0+03b0 <[^>]*> 40 18 81 10 swpbx.w r1 ;
|
0+03b8 <[^>]*> 00 18 90 10 00 00 swpbx.a 0x0000 ;PC rel. 0x03bc
|
||||||
0+03b4 <[^>]*> 00 18 90 10 00 00 swpbx.a 0x0000 ;PC rel. 0x03b8
|
0+03be <[^>]*> 40 18 8c 10 swpbx.w r12 ;
|
||||||
0+03ba <[^>]*> 40 18 8c 10 swpbx.w r12 ;
|
0+03c2 <[^>]*> 40 18 82 11 sxtx.w r2 ;
|
||||||
0+03be <[^>]*> 40 18 82 11 sxtx.w r2 ;
|
0+03c6 <[^>]*> 00 18 92 11 00 00 sxtx.a &0x0000 ;
|
||||||
0+03c2 <[^>]*> 00 18 92 11 00 00 sxtx.a &0x0000 ;
|
0+03cc <[^>]*> 40 18 82 11 sxtx.w r2 ;
|
||||||
0+03c8 <[^>]*> 40 18 82 11 sxtx.w r2 ;
|
0+03d0 <[^>]*> 04 18 45 11 rpt #5 \{ rrax.a r5 ;
|
||||||
0+03cc <[^>]*> 04 18 45 11 rpt #5 \{ rrax.a r5 ;
|
0+03d4 <[^>]*> 85 18 45 11 rpt r5 \{ rrax.a r5 ;
|
||||||
0+03d0 <[^>]*> 85 18 45 11 rpt r5 \{ rrax.a r5 ;
|
0+03d8 <[^>]*> e2 01 adda r1, r2 ;
|
||||||
0+03d4 <[^>]*> e2 01 adda r1, r2 ;
|
0+03da <[^>]*> c0 01 mova r1, r0 ;
|
||||||
0+03d6 <[^>]*> c0 01 mova r1, r0 ;
|
0+03dc <[^>]*> 41 13 calla r1 ;
|
||||||
0+03d8 <[^>]*> 41 13 calla r1 ;
|
0+03de <[^>]*> 40 18 01 43 clrx.w r1 ;
|
||||||
0+03da <[^>]*> 40 18 01 43 clrx.w r1 ;
|
0+03e2 <[^>]*> d2 01 cmpa r1, r2 ;
|
||||||
0+03de <[^>]*> d2 01 cmpa r1, r2 ;
|
0+03e4 <[^>]*> 40 18 21 83 decdx.w r1 ;
|
||||||
0+03e0 <[^>]*> 40 18 21 83 decdx.w r1 ;
|
0+03e8 <[^>]*> 40 18 21 53 incdx.w r1 ;
|
||||||
0+03e4 <[^>]*> 40 18 21 53 incdx.w r1 ;
|
0+03ec <[^>]*> c2 01 mova r1, r2 ;
|
||||||
0+03e8 <[^>]*> c2 01 mova r1, r2 ;
|
0+03ee <[^>]*> 10 01 reta ;
|
||||||
0+03ea <[^>]*> 10 01 reta ;
|
0+03f0 <[^>]*> f2 01 suba r1, r2 ;
|
||||||
0+03ec <[^>]*> f2 01 suba r1, r2 ;
|
0+03f2 <[^>]*> 40 18 80 93 00 00 cmpx.w #0, 0x00000 ;r3 As==00, PC rel. 0x003f6
|
||||||
0+03ee <[^>]*> 40 18 80 93 00 00 cmpx.w #0, 0x00000 ;r3 As==00, PC rel. 0x003f2
|
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 ;
|
||||||
|
|
|
@ -274,4 +274,10 @@ foo:
|
||||||
sub.a r1, r2
|
sub.a r1, r2
|
||||||
tst.a fooz
|
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
|
||||||
|
|
|
@ -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>
|
2016-01-19 John Baldwin <jhb@FreeBSD.org>
|
||||||
|
|
||||||
* elf/common.h (NT_FREEBSD_THRMISC): Define.
|
* elf/common.h (NT_FREEBSD_THRMISC): Define.
|
||||||
|
|
|
@ -35,7 +35,13 @@ struct msp430_operand_s
|
||||||
#endif
|
#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
|
struct msp430_opcode_s
|
||||||
{
|
{
|
||||||
|
@ -46,7 +52,7 @@ struct msp430_opcode_s
|
||||||
int bin_mask;
|
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[] =
|
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 (pushx, -3, 1, 0x1200, 0xff80),
|
||||||
MSP_INSN (rrax, -3, 1, 0x1100, 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 (swpbx, -3, 1, 0x1080, 0xffc0),
|
||||||
MSP_INSN (sxtx, -3, 1, 0x1180, 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 (rlam, -1, 6, 0x0240, 0xf3e0),
|
||||||
MSP_INSN (rrum, -1, 6, 0x0340, 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 (adda, -1, 8, 0x00a0, 0xf0b0),
|
||||||
MSP_INSN (cmpa, -1, 8, 0x0090, 0xf0b0),
|
MSP_INSN (cmpa, -1, 8, 0x0090, 0xf0b0),
|
||||||
MSP_INSN (suba, -1, 8, 0x00b0, 0xf0b0),
|
MSP_INSN (suba, -1, 8, 0x00b0, 0xf0b0),
|
||||||
|
|
|
@ -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>
|
2016-02-02 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* cgen-ibld.in (insert_normal): Rework calculation of shift.
|
* cgen-ibld.in (insert_normal): Rework calculation of shift.
|
||||||
|
|
|
@ -1102,7 +1102,7 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
||||||
}
|
}
|
||||||
else if (extension_word)
|
else if (extension_word)
|
||||||
{
|
{
|
||||||
if (extension_word & (1 << 6))
|
if (extension_word & BYTE_OPERATION)
|
||||||
bc = ".w";
|
bc = ".w";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1181,7 +1181,12 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
|
||||||
prin (stream, "rpt #%d { ", (extension_word & 0xf) + 1);
|
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);
|
(*prin) (stream, "%sx%s", opcode->name, bc);
|
||||||
else
|
else
|
||||||
(*prin) (stream, "%s%s", opcode->name, bc);
|
(*prin) (stream, "%s%s", opcode->name, bc);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue