Fix MSP430 assembler's detection of NOP and EINT.
authorNick Clifton <nickc@redhat.com>
Wed, 6 Apr 2016 14:57:19 +0000 (15:57 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 6 Apr 2016 14:58:30 +0000 (15:58 +0100)
* 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.

gas/ChangeLog
gas/config/tc-msp430.c
gas/testsuite/gas/msp430/bad.l
gas/testsuite/gas/msp430/bad.s

index ec9c4e2cfbdc6186bde8fc94b26c92f01f97c910..8647d9e6b6d068fb86842578ed32d84eb8d0f3c0 100644 (file)
@@ -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.
index 817ab452cac37c32e1f6206c32d55a9efd32ce96..f9df7290f5e5a49ec6148e915ebbe9e88d0706b4 100644 (file)
@@ -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;
 }
index 6cc3e3a299d64d024e2f285b310d82377e03b385..f4665133920851eaafa1ad0c70d5d32bdf21f690 100644 (file)
@@ -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
index b9c4af2e3087162d693a227469fd294ce314bb84..ae2db2f01cda4067d0f06252e0b958d50efaa844 100644 (file)
        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