diff options
author | Nick Clifton <nickc@redhat.com> | 2016-04-06 15:57:19 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2016-04-06 15:58:30 +0100 |
commit | 927f2d25ef9d9dc35d6a4061d5504b0fc928f057 (patch) | |
tree | 73575d0b8a7c5fa9646b4670ecd066c2fa10069c | |
parent | 052d2eb2545db0e052b45dd2e0ece82ebbe8a68c (diff) | |
download | gdb-927f2d25ef9d9dc35d6a4061d5504b0fc928f057.zip gdb-927f2d25ef9d9dc35d6a4061d5504b0fc928f057.tar.gz gdb-927f2d25ef9d9dc35d6a4061d5504b0fc928f057.tar.bz2 |
Fix MSP430 assembler's detection of NOP and EINT.
* config/tc-msp430.c (msp430_operands): Check for a NOP preceding
an EINT instruction. Warn/fix as necessary.
* testsuite/gas/msp430/bad.s: Add test of EINT without preceding NOP.
* testsuite/gas/msp430/bad.l: Update expected messages.
-rw-r--r-- | gas/ChangeLog | 7 | ||||
-rw-r--r-- | gas/config/tc-msp430.c | 25 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/bad.l | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/bad.s | 6 |
4 files changed, 45 insertions, 7 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ec9c4e2..8647d9e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2016-04-06 Nick Clifton <nickc@redhat.com> + + * config/tc-msp430.c (msp430_operands): Check for a NOP preceding + an EINT instruction. Warn/fix as necessary. + * testsuite/gas/msp430/bad.s: Add test of EINT without preceding NOP. + * testsuite/gas/msp430/bad.l: Update expected messages. + 2016-04-05 Andrew Burgess <andrew.burgess@embecosm.com> * testsuite/gas/arc/nps400-1.d: Update expected results. diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c index 817ab45..f9df729 100644 --- a/gas/config/tc-msp430.c +++ b/gas/config/tc-msp430.c @@ -2471,6 +2471,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) bfd_boolean addr_op; const char * error_message; static signed int repeat_count = 0; + static bfd_boolean prev_insn_is_nop = FALSE; bfd_boolean fix_emitted; /* Opcode is the one from opcodes table @@ -2670,7 +2671,24 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) switch (opcode->insn_opnumb) { case 0: - if (is_opcode ("eint") || is_opcode ("dint")) + if (is_opcode ("eint")) + { + if (! prev_insn_is_nop) + { + if (gen_interrupt_nops) + { + frag = frag_more (2); + bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag); + dwarf2_emit_insn (2); + + if (warn_interrupt_nops) + as_warn (_("inserting a NOP before EINT")); + } + else if (warn_interrupt_nops) + as_warn (_("a NOP might be needed before the EINT")); + } + } + else if (is_opcode ("dint")) check_for_nop |= NOP_CHECK_INTERRUPT; /* Set/clear bits instructions. */ @@ -3857,6 +3875,11 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) as_bad (_("Illegal instruction or not implemented opcode.")); } + if (is_opcode ("nop")) + prev_insn_is_nop = TRUE; + else + prev_insn_is_nop = FALSE; + input_line_pointer = line; return 0; } diff --git a/gas/testsuite/gas/msp430/bad.l b/gas/testsuite/gas/msp430/bad.l index 6cc3e3a..f466513 100644 --- a/gas/testsuite/gas/msp430/bad.l +++ b/gas/testsuite/gas/msp430/bad.l @@ -5,11 +5,13 @@ [^:]*:9: Error: junk found after instruction: mov.cd r1,r2 [^:]*:10: Warning: no size modifier after period, .w assumed [^:]*:11: Error: instruction bis.a does not exist -[^:]*:19: Warning: a NOP might be needed here because of successive changes in interrupt state -[^:]*:20: Warning: a NOP might be needed here because of successive changes in interrupt state -[^:]*:23: Warning: a NOP might be needed here because of successive changes in interrupt state +[^:]*:16: Warning: a NOP might be needed here because of successive changes in interrupt state +[^:]*:16: Warning: a NOP might be needed before the EINT [^:]*:25: Warning: a NOP might be needed here because of successive changes in interrupt state -[^:]*:26: Warning: a NOP might be needed here because of successive changes in interrupt state -[^:]*:27: Warning: a NOP might be needed here because of successive changes in interrupt state -[^:]*:28: Warning: a NOP might be needed here because of successive changes in interrupt state +[^:]*:25: Warning: a NOP might be needed before the EINT +[^:]*:29: Warning: a NOP might be needed here because of successive changes in interrupt state +[^:]*:31: Warning: a NOP might be needed here because of successive changes in interrupt state +[^:]*:32: Warning: a NOP might be needed here because of successive changes in interrupt state +[^:]*:33: Warning: a NOP might be needed here because of successive changes in interrupt state +[^:]*:34: Warning: a NOP might be needed here because of successive changes in interrupt state [^:]*: Warning: assembly finished without a possibly needed NOP instruction diff --git a/gas/testsuite/gas/msp430/bad.s b/gas/testsuite/gas/msp430/bad.s index b9c4af2..ae2db2f 100644 --- a/gas/testsuite/gas/msp430/bad.s +++ b/gas/testsuite/gas/msp430/bad.s @@ -11,6 +11,12 @@ bis.a #8, r2 ;;; FIXME: Add more tests of assembler error detection here. + + ;; A NOP is needed *before* an EINT instruction. + eint + nop + ;; And *after* a DINT instruction. + dint ;; Changing interrupt states in two successive instructions ;; might cause an interrupt to be missed. The assembler |