From 35ba4bc019ba75eca36363164eeaae3f011b32c9 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 27 Nov 2018 12:25:09 +0000 Subject: [PATCH] Tighten the constraints for warning about NOPs for the MSP 430 ISA, so NOPs are only inserted/warned about when needed. Specifically: 430 and 430x ISA require a NOP after DINT. Only the 430x ISA requires NOP before EINT. Only the 430x ISA requires NOP after every EINT. CPU42 errata. * config/tc-msp430.c (is_dint): New. (is_eint): New. (gen_nop): New. (warn_eint_nop): New. (warn_unsure_interrupt): New. (msp430_operands): Determine the effect MOV #N,SR insns have on interrupt state. Only emit NOP warnings for 430 ISA in certain situations. (msp430_md_end): Only warn about an EINT at the end of the file if NOP warnings are enabled. * testsuite/gas/msp430/bad.l: Adjust expected output for new warnings. * testsuite/gas/msp430/msp430.exp: Run new tests. * testsuite/gas/msp430/nop-dint-430.d: New. * testsuite/gas/msp430/nop-dint-430.l: New. * testsuite/gas/msp430/nop-dint-430x-ignore.d: New. * testsuite/gas/msp430/nop-dint-430x-silent.d: New. * testsuite/gas/msp430/nop-dint-430x.d: New. * testsuite/gas/msp430/nop-dint-430x.l: New. * testsuite/gas/msp430/nop-dint.s: New. * testsuite/gas/msp430/nop-eint-430.d: New. * testsuite/gas/msp430/nop-eint-430.l: New. * testsuite/gas/msp430/nop-eint-430x-ignore.d: New. * testsuite/gas/msp430/nop-eint-430x-silent.d: New. * testsuite/gas/msp430/nop-eint-430x.d: New. * testsuite/gas/msp430/nop-eint-430x.l: New. * testsuite/gas/msp430/nop-eint.s: New. * testsuite/gas/msp430/nop-int-430.d: New. * testsuite/gas/msp430/nop-int-430.l: New. * testsuite/gas/msp430/nop-int-430x-silent.d: New. * testsuite/gas/msp430/nop-int-430x.d: New. * testsuite/gas/msp430/nop-int-430x.l: New. * testsuite/gas/msp430/nop-int.s: New. --- gas/ChangeLog | 35 +++ gas/config/tc-msp430.c | 296 +++++++++++++++++++----- gas/testsuite/gas/msp430/bad.l | 21 +- gas/testsuite/gas/msp430/msp430.exp | 11 + gas/testsuite/gas/msp430/nop-dint-430.d | 32 +++ gas/testsuite/gas/msp430/nop-dint-430.l | 9 + gas/testsuite/gas/msp430/nop-dint-430x-ignore.d | 8 + gas/testsuite/gas/msp430/nop-dint-430x-silent.d | 31 +++ gas/testsuite/gas/msp430/nop-dint-430x.d | 32 +++ gas/testsuite/gas/msp430/nop-dint-430x.l | 9 + gas/testsuite/gas/msp430/nop-dint.s | 37 +++ gas/testsuite/gas/msp430/nop-eint-430.d | 31 +++ gas/testsuite/gas/msp430/nop-eint-430.l | 3 + gas/testsuite/gas/msp430/nop-eint-430x-ignore.d | 8 + gas/testsuite/gas/msp430/nop-eint-430x-silent.d | 47 ++++ gas/testsuite/gas/msp430/nop-eint-430x.d | 48 ++++ gas/testsuite/gas/msp430/nop-eint-430x.l | 20 ++ gas/testsuite/gas/msp430/nop-eint.s | 44 ++++ gas/testsuite/gas/msp430/nop-int-430.d | 4 + gas/testsuite/gas/msp430/nop-int-430.l | 3 + gas/testsuite/gas/msp430/nop-int-430x-silent.d | 5 + gas/testsuite/gas/msp430/nop-int-430x.d | 4 + gas/testsuite/gas/msp430/nop-int-430x.l | 10 + gas/testsuite/gas/msp430/nop-int.s | 74 ++++++ 24 files changed, 751 insertions(+), 71 deletions(-) create mode 100644 gas/testsuite/gas/msp430/nop-dint-430.d create mode 100644 gas/testsuite/gas/msp430/nop-dint-430.l create mode 100644 gas/testsuite/gas/msp430/nop-dint-430x-ignore.d create mode 100644 gas/testsuite/gas/msp430/nop-dint-430x-silent.d create mode 100644 gas/testsuite/gas/msp430/nop-dint-430x.d create mode 100644 gas/testsuite/gas/msp430/nop-dint-430x.l create mode 100644 gas/testsuite/gas/msp430/nop-dint.s create mode 100644 gas/testsuite/gas/msp430/nop-eint-430.d create mode 100644 gas/testsuite/gas/msp430/nop-eint-430.l create mode 100644 gas/testsuite/gas/msp430/nop-eint-430x-ignore.d create mode 100644 gas/testsuite/gas/msp430/nop-eint-430x-silent.d create mode 100644 gas/testsuite/gas/msp430/nop-eint-430x.d create mode 100644 gas/testsuite/gas/msp430/nop-eint-430x.l create mode 100644 gas/testsuite/gas/msp430/nop-eint.s create mode 100644 gas/testsuite/gas/msp430/nop-int-430.d create mode 100644 gas/testsuite/gas/msp430/nop-int-430.l create mode 100644 gas/testsuite/gas/msp430/nop-int-430x-silent.d create mode 100644 gas/testsuite/gas/msp430/nop-int-430x.d create mode 100644 gas/testsuite/gas/msp430/nop-int-430x.l create mode 100644 gas/testsuite/gas/msp430/nop-int.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 4b02996..112b0f5 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,38 @@ +2018-11-27 Jozef Lawrynowicz + + * config/tc-msp430.c (is_dint): New. + (is_eint): New. + (gen_nop): New. + (warn_eint_nop): New. + (warn_unsure_interrupt): New. + (msp430_operands): Determine the effect MOV #N,SR insns have on + interrupt state. + Only emit NOP warnings for 430 ISA in certain situations. + (msp430_md_end): Only warn about an EINT at the end of the file + if NOP warnings are enabled. + * testsuite/gas/msp430/bad.l: Adjust expected output for new warnings. + * testsuite/gas/msp430/msp430.exp: Run new tests. + * testsuite/gas/msp430/nop-dint-430.d: New. + * testsuite/gas/msp430/nop-dint-430.l: New. + * testsuite/gas/msp430/nop-dint-430x-ignore.d: New. + * testsuite/gas/msp430/nop-dint-430x-silent.d: New. + * testsuite/gas/msp430/nop-dint-430x.d: New. + * testsuite/gas/msp430/nop-dint-430x.l: New. + * testsuite/gas/msp430/nop-dint.s: New. + * testsuite/gas/msp430/nop-eint-430.d: New. + * testsuite/gas/msp430/nop-eint-430.l: New. + * testsuite/gas/msp430/nop-eint-430x-ignore.d: New. + * testsuite/gas/msp430/nop-eint-430x-silent.d: New. + * testsuite/gas/msp430/nop-eint-430x.d: New. + * testsuite/gas/msp430/nop-eint-430x.l: New. + * testsuite/gas/msp430/nop-eint.s: New. + * testsuite/gas/msp430/nop-int-430.d: New. + * testsuite/gas/msp430/nop-int-430.l: New. + * testsuite/gas/msp430/nop-int-430x-silent.d: New. + * testsuite/gas/msp430/nop-int-430x.d: New. + * testsuite/gas/msp430/nop-int-430x.l: New. + * testsuite/gas/msp430/nop-int.s: New. + 2018-11-23 Andre Vieira * testsuite/gas/arm/bl-local-v4t.d: Remove diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c index bebae6e..d4b2407 100644 --- a/gas/config/tc-msp430.c +++ b/gas/config/tc-msp430.c @@ -2495,6 +2495,79 @@ static signed int check_for_nop = 0; #define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0) +/* is_{e,d}int only check the explicit enabling/disabling of interrupts. + For MOV insns, more sophisticated processing is needed to determine if they + result in enabling/disabling interrupts. */ +#define is_dint(OPCODE, BIN) ((strcmp (OPCODE, "dint") == 0) \ + || ((strcmp (OPCODE, "bic") == 0) \ + && BIN == 0xc232) \ + || ((strcmp (OPCODE, "clr") == 0) \ + && BIN == 0x4302)) + +#define is_eint(OPCODE, BIN) ((strcmp (OPCODE, "eint") == 0) \ + || ((strcmp (OPCODE, "bis") == 0) \ + && BIN == 0xd232)) + +const char * const INSERT_NOP_BEFORE_EINT = "NOP inserted here, before an interrupt enable instruction"; +const char * const INSERT_NOP_AFTER_DINT = "NOP inserted here, after an interrupt disable instruction"; +const char * const INSERT_NOP_AFTER_EINT = "NOP inserted here, after an interrupt enable instruction"; +const char * const INSERT_NOP_BEFORE_UNKNOWN = "NOP inserted here, before this interrupt state change"; +const char * const INSERT_NOP_AFTER_UNKNOWN ="NOP inserted here, after the instruction that changed interrupt state"; +const char * const INSERT_NOP_AT_EOF = "NOP inserted after the interrupt state change at the end of the file"; + +const char * const WARN_NOP_BEFORE_EINT = "a NOP might be needed here, before an interrupt enable instruction"; +const char * const WARN_NOP_AFTER_DINT = "a NOP might be needed here, after an interrupt disable instruction"; +const char * const WARN_NOP_AFTER_EINT = "a NOP might be needed here, after an interrupt enable instruction"; +const char * const WARN_NOP_BEFORE_UNKNOWN = "a NOP might be needed here, before this interrupt state change"; +const char * const WARN_NOP_AFTER_UNKNOWN = "a NOP might also be needed here, after the instruction that changed interrupt state"; +const char * const WARN_NOP_AT_EOF = "a NOP might be needed after the interrupt state change at the end of the file"; + +static void +gen_nop (void) +{ + char *frag; + frag = frag_more (2); + bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag); + dwarf2_emit_insn (2); +} + +/* Insert/inform about adding a NOP if this insn enables interrupts. */ +static void +warn_eint_nop (bfd_boolean prev_insn_is_nop, bfd_boolean prev_insn_is_dint) +{ + if (prev_insn_is_nop + /* Prevent double warning for DINT immediately before EINT. */ + || prev_insn_is_dint + /* 430 ISA does not require a NOP before EINT. */ + || (! target_is_430x ())) + return; + if (gen_interrupt_nops) + { + gen_nop (); + if (warn_interrupt_nops) + as_warn (_(INSERT_NOP_BEFORE_EINT)); + } + else if (warn_interrupt_nops) + as_warn (_(WARN_NOP_BEFORE_EINT)); +} + +/* Use when unsure what effect the insn will have on the interrupt status, + to insert/warn about adding a NOP before the current insn. */ +static void +warn_unsure_interrupt (void) +{ + /* Since this could enable or disable interrupts, need to add/warn about + adding a NOP before and after this insn. */ + if (gen_interrupt_nops) + { + gen_nop (); + if (warn_interrupt_nops) + as_warn (_(INSERT_NOP_BEFORE_UNKNOWN)); + } + else if (warn_interrupt_nops) + as_warn (_(WARN_NOP_BEFORE_UNKNOWN)); +} + /* Parse instruction operands. Return binary opcode. */ @@ -2519,6 +2592,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) const char * error_message; static signed int repeat_count = 0; static bfd_boolean prev_insn_is_nop = FALSE; + static bfd_boolean prev_insn_is_dint = FALSE; + static bfd_boolean prev_insn_is_eint = FALSE; + /* We might decide before the end of the function that the current insn is + equivalent to DINT/EINT. */ + bfd_boolean this_insn_is_dint = FALSE; + bfd_boolean this_insn_is_eint = FALSE; bfd_boolean fix_emitted; /* Opcode is the one from opcodes table @@ -2654,29 +2733,69 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) repeat_count = 0; } + /* The previous instruction set this flag if it wants to check if this insn + is a NOP. */ if (check_for_nop) { if (! is_opcode ("nop")) { - bfd_boolean doit = FALSE; - do { switch (check_for_nop & - check_for_nop) { case NOP_CHECK_INTERRUPT: - if (warn_interrupt_nops) + /* NOP_CHECK_INTERRUPT rules: + 1. 430 and 430x ISA require a NOP after DINT. + 2. Only the 430x ISA requires NOP before EINT (this has + been dealt with in the previous call to this function). + 3. Only the 430x ISA requires NOP after every EINT. + CPU42 errata. */ + if (gen_interrupt_nops || warn_interrupt_nops) { - if (gen_interrupt_nops) - as_warn (_("NOP inserted between two instructions that change interrupt state")); + if (prev_insn_is_dint) + { + if (gen_interrupt_nops) + { + gen_nop (); + if (warn_interrupt_nops) + as_warn (_(INSERT_NOP_AFTER_DINT)); + } + else + as_warn (_(WARN_NOP_AFTER_DINT)); + } + else if (prev_insn_is_eint) + { + if (gen_interrupt_nops) + { + gen_nop (); + if (warn_interrupt_nops) + as_warn (_(INSERT_NOP_AFTER_EINT)); + } + else + as_warn (_(WARN_NOP_AFTER_EINT)); + } + /* If we get here it's because the last instruction was + determined to either disable or enable interrupts, but + we're not sure which. + We have no information yet about what effect the + current instruction has on interrupts, that has to be + sorted out later. + The last insn may have required a NOP after it, so we + deal with that now. */ else - as_warn (_("a NOP might be needed here because of successive changes in interrupt state")); + { + if (gen_interrupt_nops) + { + gen_nop (); + if (warn_interrupt_nops) + as_warn (_(INSERT_NOP_AFTER_UNKNOWN)); + } + else + /* warn_unsure_interrupt was called on the previous + insn. */ + as_warn (_(WARN_NOP_AFTER_UNKNOWN)); + } } - - if (gen_interrupt_nops) - /* Emit a NOP between interrupt enable/disable. - See 1.3.4.1 of the MSP430x5xx User Guide. */ - doit = TRUE; break; case NOP_CHECK_CPU12: @@ -2684,7 +2803,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) as_warn (_("CPU12: CMP/BIT with PC destination ignores next instruction")); if (silicon_errata_fix & SILICON_ERRATA_CPU12) - doit = TRUE; + gen_nop (); break; case NOP_CHECK_CPU19: @@ -2692,7 +2811,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) as_warn (_("CPU19: Instruction setting CPUOFF must be followed by a NOP")); if (silicon_errata_fix & SILICON_ERRATA_CPU19) - doit = TRUE; + gen_nop (); break; default: @@ -2702,15 +2821,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) check_for_nop &= ~ (check_for_nop & - check_for_nop); } while (check_for_nop); - - if (doit) - { - frag = frag_more (2); - bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag); - dwarf2_emit_insn (2); - } } - check_for_nop = 0; } @@ -2721,24 +2832,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) { case 0: 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; + warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); /* Set/clear bits instructions. */ if (extended_op) @@ -2796,9 +2890,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) as_warn (_("CPU13: SR is destination of SR altering instruction")); } - if (is_opcode ("clr") && bin == 0x4302 /* CLR R2*/) - check_for_nop |= NOP_CHECK_INTERRUPT; - /* Compute the entire instruction length, in bytes. */ op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2); insn_length += op_length; @@ -2896,6 +2987,8 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) /* ... and the opcode alters the SR. */ && (is_opcode ("rla") || is_opcode ("rlc") || is_opcode ("rlax") || is_opcode ("rlcx") + || is_opcode ("sxt") || is_opcode ("sxtx") + || is_opcode ("swpb") )) { if (silicon_errata_fix & SILICON_ERRATA_CPU13) @@ -3447,6 +3540,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) } break; + /* FIXME: Emit warning when dest reg SR(R2) is addressed with .B or .A. + From f5 ref man 6.3.3: + The 16-bit Status Register (SR, also called R2), used as a source or + destination register, can only be used in register mode addressed + with word instructions. */ + case 1: /* Format 1, double operand. */ line = extract_operand (line, l1, sizeof (l1)); line = extract_operand (line, l2, sizeof (l2)); @@ -3501,20 +3600,9 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) else if (silicon_errata_warn & SILICON_ERRATA_CPU13) as_warn (_("CPU13: SR is destination of SR altering instruction")); } - - if ( (is_opcode ("bic") && bin == 0xc232) - || (is_opcode ("bis") && bin == 0xd232) - || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)) - { - /* Avoid false checks when a constant value is being put into the SR. */ - if (op1.mode == OP_EXP - && op1.exp.X_op == O_constant - && (op1.exp.X_add_number & 0x8) != 0x8) - ; - else - check_for_nop |= NOP_CHECK_INTERRUPT; - } + /* Chain these checks for SR manipulations so we can warn if they are not + caught. */ if (((is_opcode ("bis") && bin == 0xd032) || (is_opcode ("mov") && bin == 0x4032) || (is_opcode ("xor") && bin == 0xe032)) @@ -3522,6 +3610,60 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) && op1.exp.X_op == O_constant && (op1.exp.X_add_number & 0x10) == 0x10) check_for_nop |= NOP_CHECK_CPU19; + else if ((is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)) + { + /* Any MOV with the SR as the destination either enables or disables + interrupts. */ + if (op1.mode == OP_EXP + && op1.exp.X_op == O_constant) + { + if ((op1.exp.X_add_number & 0x8) == 0x8) + { + /* The GIE bit is being set. */ + warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); + this_insn_is_eint = TRUE; + } + else + /* The GIE bit is being cleared. */ + this_insn_is_dint = TRUE; + } + /* If an immediate value which is covered by the constant generator + is the src, then op1 will have been changed to either R2 or R3 by + this point. + The only constants covered by CG1 and CG2, which have bit 3 set + and therefore would enable interrupts when writing to the SR, are + R2 with addresing mode 0b11 and R3 with 0b11. + The addressing mode is in bits 5:4 of the binary opcode. */ + else if (op1.mode == OP_REG + && (op1.reg == 2 || op1.reg == 3) + && (bin & 0x30) == 0x30) + { + warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); + this_insn_is_eint = TRUE; + } + /* Any other use of the constant generator with destination R2, will + disable interrupts. */ + else if (op1.mode == OP_REG + && (op1.reg == 2 || op1.reg == 3)) + this_insn_is_dint = TRUE; + else + { + /* FIXME: Couldn't work out whether the insn is enabling or + disabling interrupts, so for safety need to treat it as both + a DINT and EINT. */ + warn_unsure_interrupt (); + check_for_nop |= NOP_CHECK_INTERRUPT; + } + } + else if (is_eint (opcode->name, bin)) + warn_eint_nop (prev_insn_is_nop, prev_insn_is_dint); + else if ((bin & 0x32) == 0x32) + { + /* Double-operand insn with the As==0b11 and Rdst==0x2 will result in + * an interrupt state change if a write happens. */ + /* FIXME: How strict to be here? */ + ; + } /* Compute the entire length of the instruction in bytes. */ op_length = (extended_op ? 2 : 0) /* The extension word. */ @@ -3959,11 +4101,34 @@ 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; - + if (is_opcode ("nop")) + { + prev_insn_is_nop = TRUE; + prev_insn_is_dint = FALSE; + prev_insn_is_eint = FALSE; + } + else if (this_insn_is_dint || is_dint (opcode->name, bin)) + { + prev_insn_is_dint = TRUE; + prev_insn_is_eint = FALSE; + prev_insn_is_nop = FALSE; + check_for_nop |= NOP_CHECK_INTERRUPT; + } + /* NOP is not needed after EINT for 430 ISA. */ + else if (target_is_430x () && (this_insn_is_eint || is_eint (opcode->name, bin))) + { + prev_insn_is_eint = TRUE; + prev_insn_is_nop = FALSE; + prev_insn_is_dint = FALSE; + check_for_nop |= NOP_CHECK_INTERRUPT; + } + else + { + prev_insn_is_nop = FALSE; + prev_insn_is_dint = FALSE; + prev_insn_is_eint = FALSE; + } + input_line_pointer = line; return 0; } @@ -4699,7 +4864,16 @@ void msp430_md_end (void) { if (check_for_nop) - as_warn ("assembly finished without a possibly needed NOP instruction"); + { + if (gen_interrupt_nops) + { + gen_nop (); + if (warn_interrupt_nops) + as_warn (INSERT_NOP_AT_EOF); + } + else if (warn_interrupt_nops) + as_warn (_(WARN_NOP_AT_EOF)); + } bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA, target_is_430x () ? 2 : 1); diff --git a/gas/testsuite/gas/msp430/bad.l b/gas/testsuite/gas/msp430/bad.l index f466513..7b68583 100644 --- a/gas/testsuite/gas/msp430/bad.l +++ b/gas/testsuite/gas/msp430/bad.l @@ -4,14 +4,15 @@ [^:]*:8: Error: junk found after instruction: mov.cd r1,r2 [^:]*:9: Error: junk found after instruction: mov.cd r1,r2 [^:]*:10: Warning: no size modifier after period, .w assumed +[^:]*:10: Warning: a NOP might be needed here, before this interrupt state change [^:]*:11: Error: instruction bis.a does not exist -[^:]*: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 -[^:]*: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 +[^:]*:16: Warning: a NOP might also be needed here, after the instruction that changed interrupt state +[^:]*:16: Warning: a NOP might be needed here, before an interrupt enable instruction +[^:]*:25: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*:26: Warning: a NOP might be needed here, after an interrupt enable instruction +[^:]*:29: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*:31: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*:32: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*:33: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*:34: Warning: a NOP might be needed here, after an interrupt enable instruction +[^:]*: Warning: a NOP might be needed after the interrupt state change at the end of the file diff --git a/gas/testsuite/gas/msp430/msp430.exp b/gas/testsuite/gas/msp430/msp430.exp index 5e77b9b..1bc45be 100644 --- a/gas/testsuite/gas/msp430/msp430.exp +++ b/gas/testsuite/gas/msp430/msp430.exp @@ -27,4 +27,15 @@ if [expr [istarget "msp430-*-*"]] then { run_dump_test "high-data-bss-sym" { { as "-mdata-region=upper" } } run_dump_test "high-data-bss-sym" { { as "-mdata-region=either" } } run_dump_test "pr22133" + run_dump_test "nop-int-430" + run_dump_test "nop-int-430x" + run_dump_test "nop-int-430x-silent" + run_dump_test "nop-eint-430" + run_dump_test "nop-eint-430x" + run_dump_test "nop-eint-430x-silent" + run_dump_test "nop-eint-430x-ignore" + run_dump_test "nop-dint-430" + run_dump_test "nop-dint-430x" + run_dump_test "nop-dint-430x-silent" + run_dump_test "nop-dint-430x-ignore" } diff --git a/gas/testsuite/gas/msp430/nop-dint-430.d b/gas/testsuite/gas/msp430/nop-dint-430.d new file mode 100644 index 0000000..99eb00b --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-dint-430.d @@ -0,0 +1,32 @@ +#name: DINT NOP Insertions (MSP430 CPU) +#source: nop-dint.s +#as: -my -mn -mcpu=430 +#warning_output: nop-dint-430.l +#objdump: -d --prefix-addresses --show-raw-insn + +.*: +file format .*msp.* + +Disassembly of section .text: +0x0+000 32 c2[ ]+dint[ ]+ +0x0+002 03 43[ ]+nop[ ]+ +0x0+004 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+008 32 c2[ ]+dint[ ]+ +0x0+00a 03 43[ ]+nop[ ]+ +0x0+00c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+010 32 c2[ ]+dint[ ]+ +0x0+012 03 43[ ]+nop[ ]+ +0x0+014 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+018 02 43[ ]+clr r2 ; +0x0+01a 03 43[ ]+nop[ ]+ +0x0+01c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+020 32 40 07 00[ ]+mov #7, r2 ; +0x0+024 03 43[ ]+nop[ ]+ +0x0+026 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+02a 32 40 07 f0[ ]+mov #-4089, r2 ;#0xf007 +0x0+02e 03 43[ ]+nop[ ]+ +0x0+030 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+034 02 43[ ]+clr r2 ; +0x0+036 03 43[ ]+nop[ ]+ +0x0+038 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+03c 32 c2[ ]+dint[ ]+ +0x0+03e 03 43[ ]+nop[ ]+ diff --git a/gas/testsuite/gas/msp430/nop-dint-430.l b/gas/testsuite/gas/msp430/nop-dint-430.l new file mode 100644 index 0000000..ab1adec --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-dint-430.l @@ -0,0 +1,9 @@ +[^:]*: Assembler messages: +[^:]*:11: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:15: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:18: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:21: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:24: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:27: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:30: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*: Warning: NOP inserted after the interrupt state change at the end of the file diff --git a/gas/testsuite/gas/msp430/nop-dint-430x-ignore.d b/gas/testsuite/gas/msp430/nop-dint-430x-ignore.d new file mode 100644 index 0000000..e9265ae --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-dint-430x-ignore.d @@ -0,0 +1,8 @@ +#name: Ignore DINT NOP Insertions (MSP430X CPU) +#source: nop-dint.s +#as: -mY -mcpu=430x +#objdump: -d --prefix-addresses --show-raw-insn +#failif +#... +0x0.*nop.* +#... diff --git a/gas/testsuite/gas/msp430/nop-dint-430x-silent.d b/gas/testsuite/gas/msp430/nop-dint-430x-silent.d new file mode 100644 index 0000000..66c1052 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-dint-430x-silent.d @@ -0,0 +1,31 @@ +#name: Silent DINT NOP Insertions (MSP430X CPU) +#source: nop-dint.s +#as: -mY -mn -mcpu=430x +#objdump: -d --prefix-addresses --show-raw-insn + +.*: +file format .*msp.* + +Disassembly of section .text: +0x0+000 32 c2[ ]+dint[ ]+ +0x0+002 03 43[ ]+nop[ ]+ +0x0+004 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+008 32 c2[ ]+dint[ ]+ +0x0+00a 03 43[ ]+nop[ ]+ +0x0+00c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+010 32 c2[ ]+dint[ ]+ +0x0+012 03 43[ ]+nop[ ]+ +0x0+014 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+018 02 43[ ]+clr r2 ; +0x0+01a 03 43[ ]+nop[ ]+ +0x0+01c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+020 32 40 07 00[ ]+mov #7, r2 ; +0x0+024 03 43[ ]+nop[ ]+ +0x0+026 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+02a 32 40 07 f0[ ]+mov #-4089, r2 ;#0xf007 +0x0+02e 03 43[ ]+nop[ ]+ +0x0+030 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+034 02 43[ ]+clr r2 ; +0x0+036 03 43[ ]+nop[ ]+ +0x0+038 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+03c 32 c2[ ]+dint[ ]+ +0x0+03e 03 43[ ]+nop[ ]+ diff --git a/gas/testsuite/gas/msp430/nop-dint-430x.d b/gas/testsuite/gas/msp430/nop-dint-430x.d new file mode 100644 index 0000000..ea74dfc --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-dint-430x.d @@ -0,0 +1,32 @@ +#name: DINT NOP Insertions (MSP430X CPU) +#source: nop-dint.s +#as: -my -mn -mcpu=430x +#warning_output: nop-dint-430.l +#objdump: -d --prefix-addresses --show-raw-insn + +.*: +file format .*msp.* + +Disassembly of section .text: +0x0+000 32 c2[ ]+dint[ ]+ +0x0+002 03 43[ ]+nop[ ]+ +0x0+004 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+008 32 c2[ ]+dint[ ]+ +0x0+00a 03 43[ ]+nop[ ]+ +0x0+00c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+010 32 c2[ ]+dint[ ]+ +0x0+012 03 43[ ]+nop[ ]+ +0x0+014 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+018 02 43[ ]+clr r2 ; +0x0+01a 03 43[ ]+nop[ ]+ +0x0+01c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+020 32 40 07 00[ ]+mov #7, r2 ; +0x0+024 03 43[ ]+nop[ ]+ +0x0+026 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+02a 32 40 07 f0[ ]+mov #-4089, r2 ;#0xf007 +0x0+02e 03 43[ ]+nop[ ]+ +0x0+030 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+034 02 43[ ]+clr r2 ; +0x0+036 03 43[ ]+nop[ ]+ +0x0+038 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+03c 32 c2[ ]+dint[ ]+ +0x0+03e 03 43[ ]+nop[ ]+ diff --git a/gas/testsuite/gas/msp430/nop-dint-430x.l b/gas/testsuite/gas/msp430/nop-dint-430x.l new file mode 100644 index 0000000..ab1adec --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-dint-430x.l @@ -0,0 +1,9 @@ +[^:]*: Assembler messages: +[^:]*:11: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:15: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:18: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:21: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:24: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:27: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:30: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*: Warning: NOP inserted after the interrupt state change at the end of the file diff --git a/gas/testsuite/gas/msp430/nop-dint.s b/gas/testsuite/gas/msp430/nop-dint.s new file mode 100644 index 0000000..3dc8019 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-dint.s @@ -0,0 +1,37 @@ + .text + +;;; Test for NOP warnings when disabling interrupts, which are common to both +;;; 430 and 430x ISA. +;;; "MOV &FOO,r10" is used as an artbitrary statement which isn't a NOP, to +;;; break up the instructions being tested. + +;;; Test NOP required after DINT + DINT + + MOV &FOO,r10 +;;; Check aliases for which the GIE bit (bit 3) of the SR can be cleared +;;; These should all cause warnings + BIC.W #8,R2 + MOV &FOO,r10 + + BIC.W #8,SR + MOV &FOO,r10 + + MOV.W #0,R2 + MOV &FOO,r10 + + MOV.W #7,R2 + MOV &FOO,r10 + + MOV.W #0xf007,R2 + MOV &FOO,r10 + + CLR R2 + MOV &FOO,r10 + +;;; The above hopefully covers the legitimate ways the SR might be cleared, +;;; but there are other insns that can technically modify R2, but shouldn't be +;;; used. + +;;; Test DINT at end of file + DINT diff --git a/gas/testsuite/gas/msp430/nop-eint-430.d b/gas/testsuite/gas/msp430/nop-eint-430.d new file mode 100644 index 0000000..37b2c6c --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-eint-430.d @@ -0,0 +1,31 @@ +#name: EINT NOP Insertions (MSP430 CPU) +#source: nop-eint.s +#as: -my -mn -mcpu=430 +#warning_output: nop-eint-430.l +#objdump: -d --prefix-addresses --show-raw-insn + +.*: +file format .*msp.* + + +Disassembly of section .text: +0x0+0000 32 d2[ ]+eint[ ]+ +0x0+0002 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0006 32 d2[ ]+eint[ ]+ +0x0+0008 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+000c 32 d2[ ]+eint[ ]+ +0x0+000e 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0012 32 42[ ]+mov #8, r2 ;r2 As==11 +0x0+0014 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0018 32 40 0f 00[ ]+mov #15, r2 ;#0x000f +0x0+001c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0020 32 43[ ]+mov #-1, r2 ;r3 As==11 +0x0+0022 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0026 32 d2[ ]+eint[ ]+ +0x0+0028 32 c2[ ]+dint[ ]+ +0x0+002a 03 43[ ]+nop[ ]+ +0x0+002c 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0030 32 c2[ ]+dint[ ]+ +0x0+0032 03 43[ ]+nop[ ]+ +0x0+0034 32 d2[ ]+eint[ ]+ +0x0+0036 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+003a 32 d2[ ]+eint[ ]+ diff --git a/gas/testsuite/gas/msp430/nop-eint-430.l b/gas/testsuite/gas/msp430/nop-eint-430.l new file mode 100644 index 0000000..a7bb342 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-eint-430.l @@ -0,0 +1,3 @@ +[^:]*: Assembler messages: +[^:]*:36: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:39: Warning: NOP inserted here, after an interrupt disable instruction diff --git a/gas/testsuite/gas/msp430/nop-eint-430x-ignore.d b/gas/testsuite/gas/msp430/nop-eint-430x-ignore.d new file mode 100644 index 0000000..54066c0 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-eint-430x-ignore.d @@ -0,0 +1,8 @@ +#name: Ignore EINT NOP Insertions (MSP430X CPU) +#source: nop-eint.s +#as: -mY -mcpu=430x +#objdump: -d --prefix-addresses --show-raw-insn +#failif +#... +0x0.*nop.* +#... diff --git a/gas/testsuite/gas/msp430/nop-eint-430x-silent.d b/gas/testsuite/gas/msp430/nop-eint-430x-silent.d new file mode 100644 index 0000000..ee7b362 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-eint-430x-silent.d @@ -0,0 +1,47 @@ +#name: Silent EINT NOP Insertions (MSP430X CPU) +#source: nop-eint.s +#as: -mY -mn -mcpu=430x +#objdump: -d --prefix-addresses --show-raw-insn + +.*: +file format .*msp.* + + +Disassembly of section .text: +0x0+0000 03 43[ ]+nop[ ]+ +0x0+0002 32 d2[ ]+eint[ ]+ +0x0+0004 03 43[ ]+nop[ ]+ +0x0+0006 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+000a 03 43[ ]+nop[ ]+ +0x0+000c 32 d2[ ]+eint[ ]+ +0x0+000e 03 43[ ]+nop[ ]+ +0x0+0010 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0014 03 43[ ]+nop[ ]+ +0x0+0016 32 d2[ ]+eint[ ]+ +0x0+0018 03 43[ ]+nop[ ]+ +0x0+001a 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+001e 03 43[ ]+nop[ ]+ +0x0+0020 32 42[ ]+mov #8, r2 ;r2 As==11 +0x0+0022 03 43[ ]+nop[ ]+ +0x0+0024 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0028 03 43[ ]+nop[ ]+ +0x0+002a 32 40 0f 00[ ]+mov #15, r2 ;#0x000f +0x0+002e 03 43[ ]+nop[ ]+ +0x0+0030 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0034 03 43[ ]+nop[ ]+ +0x0+0036 32 43[ ]+mov #-1, r2 ;r3 As==11 +0x0+0038 03 43[ ]+nop[ ]+ +0x0+003a 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+003e 03 43[ ]+nop[ ]+ +0x0+0040 32 d2[ ]+eint[ ]+ +0x0+0042 03 43[ ]+nop[ ]+ +0x0+0044 32 c2[ ]+dint[ ]+ +0x0+0046 03 43[ ]+nop[ ]+ +0x0+0048 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+004c 32 c2[ ]+dint[ ]+ +0x0+004e 03 43[ ]+nop[ ]+ +0x0+0050 32 d2[ ]+eint[ ]+ +0x0+0052 03 43[ ]+nop[ ]+ +0x0+0054 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0058 03 43[ ]+nop[ ]+ +0x0+005a 32 d2[ ]+eint[ ]+ +0x0+005c 03 43[ ]+nop[ ]+ diff --git a/gas/testsuite/gas/msp430/nop-eint-430x.d b/gas/testsuite/gas/msp430/nop-eint-430x.d new file mode 100644 index 0000000..a28459b --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-eint-430x.d @@ -0,0 +1,48 @@ +#name: EINT NOP Insertions (MSP430X CPU) +#source: nop-eint.s +#as: -my -mn -mcpu=430x +#warning_output: nop-eint-430x.l +#objdump: -d --prefix-addresses --show-raw-insn + +.*: +file format .*msp.* + + +Disassembly of section .text: +0x0+0000 03 43[ ]+nop[ ]+ +0x0+0002 32 d2[ ]+eint[ ]+ +0x0+0004 03 43[ ]+nop[ ]+ +0x0+0006 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+000a 03 43[ ]+nop[ ]+ +0x0+000c 32 d2[ ]+eint[ ]+ +0x0+000e 03 43[ ]+nop[ ]+ +0x0+0010 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0014 03 43[ ]+nop[ ]+ +0x0+0016 32 d2[ ]+eint[ ]+ +0x0+0018 03 43[ ]+nop[ ]+ +0x0+001a 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+001e 03 43[ ]+nop[ ]+ +0x0+0020 32 42[ ]+mov #8, r2 ;r2 As==11 +0x0+0022 03 43[ ]+nop[ ]+ +0x0+0024 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0028 03 43[ ]+nop[ ]+ +0x0+002a 32 40 0f 00[ ]+mov #15, r2 ;#0x000f +0x0+002e 03 43[ ]+nop[ ]+ +0x0+0030 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0034 03 43[ ]+nop[ ]+ +0x0+0036 32 43[ ]+mov #-1, r2 ;r3 As==11 +0x0+0038 03 43[ ]+nop[ ]+ +0x0+003a 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+003e 03 43[ ]+nop[ ]+ +0x0+0040 32 d2[ ]+eint[ ]+ +0x0+0042 03 43[ ]+nop[ ]+ +0x0+0044 32 c2[ ]+dint[ ]+ +0x0+0046 03 43[ ]+nop[ ]+ +0x0+0048 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+004c 32 c2[ ]+dint[ ]+ +0x0+004e 03 43[ ]+nop[ ]+ +0x0+0050 32 d2[ ]+eint[ ]+ +0x0+0052 03 43[ ]+nop[ ]+ +0x0+0054 1a 42 00 00[ ]+mov &0x0000,r10 ;0x0000 +0x0+0058 03 43[ ]+nop[ ]+ +0x0+005a 32 d2[ ]+eint[ ]+ +0x0+005c 03 43[ ]+nop[ ]+ diff --git a/gas/testsuite/gas/msp430/nop-eint-430x.l b/gas/testsuite/gas/msp430/nop-eint-430x.l new file mode 100644 index 0000000..0e97208 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-eint-430x.l @@ -0,0 +1,20 @@ +[^:]*: Assembler messages: +[^:]*:7: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*:9: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:12: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*:13: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:15: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*:16: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:18: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*:19: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:21: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*:22: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:24: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*:25: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:33: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*:34: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:36: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:39: Warning: NOP inserted here, after an interrupt disable instruction +[^:]*:41: Warning: NOP inserted here, after an interrupt enable instruction +[^:]*:44: Warning: NOP inserted here, before an interrupt enable instruction +[^:]*: Warning: NOP inserted after the interrupt state change at the end of the file diff --git a/gas/testsuite/gas/msp430/nop-eint.s b/gas/testsuite/gas/msp430/nop-eint.s new file mode 100644 index 0000000..07e3238 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-eint.s @@ -0,0 +1,44 @@ + .text + +;;; Test for NOP warnings when enabling interrupts, which only applies to 430x +;;; ISA. +;;; "MOV &FOO,r10" is used as an artbitrary statement which isn't a NOP, to +;;; break up the instructions being tested. + EINT + + MOV &FOO,r10 +;;; Check aliases for which the GIE bit (bit 3) of the SR can be set +;;; These should all cause warnings + BIS.W #8,R2 + MOV &FOO,r10 + + BIS.W #8,SR + MOV &FOO,r10 + + MOV.W #8,R2 + MOV &FOO,r10 + + MOV #0xf,R2 + MOV &FOO,r10 + + MOV #0xffff,R2 + MOV &FOO,r10 + +;;; The above hopefully covers the legitimate ways the SR might be set +;;; but there are other insns that can technically modify R2, but shouldn't be +;;; used. + +;;; Verify EINT/DINT chained behaviour + + EINT + DINT + + MOV &FOO,r10 + + DINT + EINT + + MOV &FOO,r10 + +;;; Test EINT at end of file + EINT diff --git a/gas/testsuite/gas/msp430/nop-int-430.d b/gas/testsuite/gas/msp430/nop-int-430.d new file mode 100644 index 0000000..ae8ba53 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-int-430.d @@ -0,0 +1,4 @@ +#name: Interrupt NOP Warnings (MSP430 CPU) +#source: nop-int.s +#as: -my -mcpu=430 +#warning_output: nop-int-430.l diff --git a/gas/testsuite/gas/msp430/nop-int-430.l b/gas/testsuite/gas/msp430/nop-int-430.l new file mode 100644 index 0000000..6c2a04d --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-int-430.l @@ -0,0 +1,3 @@ +[^:]*: Assembler messages: +[^:]*:60: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*:66: Warning: a NOP might be needed here, after an interrupt disable instruction diff --git a/gas/testsuite/gas/msp430/nop-int-430x-silent.d b/gas/testsuite/gas/msp430/nop-int-430x-silent.d new file mode 100644 index 0000000..5994b43 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-int-430x-silent.d @@ -0,0 +1,5 @@ +#name: Silence Interrupt NOP Warnings (MSP430X CPU) +#source: nop-int.s +#as: -mY -mcpu=430x +#objdump: -d --prefix-addresses --show-raw-insn +#pass diff --git a/gas/testsuite/gas/msp430/nop-int-430x.d b/gas/testsuite/gas/msp430/nop-int-430x.d new file mode 100644 index 0000000..9e93ed3 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-int-430x.d @@ -0,0 +1,4 @@ +#name: Interrupt NOP Warnings (MSP430X CPU) +#source: nop-int.s +#as: -my -mcpu=430x +#warning_output: nop-int-430x.l diff --git a/gas/testsuite/gas/msp430/nop-int-430x.l b/gas/testsuite/gas/msp430/nop-int-430x.l new file mode 100644 index 0000000..43f7ca2 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-int-430x.l @@ -0,0 +1,10 @@ +[^:]*: Assembler messages: +[^:]*:13: Warning: a NOP might be needed here, before an interrupt enable instruction +[^:]*:15: Warning: a NOP might be needed here, after an interrupt enable instruction +[^:]*:17: Warning: a NOP might be needed here, before an interrupt enable instruction +[^:]*:19: Warning: a NOP might be needed here, after an interrupt enable instruction +[^:]*:41: Warning: a NOP might be needed here, after an interrupt enable instruction +[^:]*:48: Warning: a NOP might be needed here, after an interrupt enable instruction +[^:]*:60: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*:66: Warning: a NOP might be needed here, after an interrupt disable instruction +[^:]*: Warning: a NOP might be needed after the interrupt state change at the end of the file diff --git a/gas/testsuite/gas/msp430/nop-int.s b/gas/testsuite/gas/msp430/nop-int.s new file mode 100644 index 0000000..efc8828 --- /dev/null +++ b/gas/testsuite/gas/msp430/nop-int.s @@ -0,0 +1,74 @@ + .text + +;;; Test some common instruction patterns for disabling/enabling interrupts. +;;; "MOV &FOO,r10" is used as an artbitrary statement which isn't a NOP, to +;;; break up the instructions being tested. + +fn1: +;;; 1: Test EINT +;; 430 ISA: NOP *not* required before *or* after EINT +;; 430x ISA: NOP *is* required before *and* after EINT + MOV &FOO,r10 + + EINT + + MOV &FOO,r10 + + BIS.W #8,SR ; Alias for EINT + + MOV &FOO,r10 +;;; 2: Test DINT +;; 430 ISA: NOP *is* required after DINT +;; 430x ISA: NOP *is* required after DINT + MOV &FOO,r10 + + DINT + NOP + + MOV &FOO,r10 + + BIC.W #8,SR ; Alias for DINT + NOP + + MOV &FOO,r10 +;;; 3: Test EINT immediately before DINT +;; 430 ISA: NOP *not* required. +;; 430x ISA: NOP *is* required between EINT and DINT + MOV &FOO,r10 + + NOP + EINT + DINT + NOP + + MOV &FOO,r10 + + NOP + BIS.W #8,SR ; Alias for EINT + BIC.W #8,SR ; Alias for DINT + NOP + + MOV &FOO,r10 +;;; 4: Test DINT immediately before EINT +;; 430 ISA: NOP *is* required after DINT. +;; 430x ISA: NOP *is* required after DINT and before EINT. Ensure only one +;; warning is emitted. + MOV &FOO,r10 + + NOP + DINT + EINT + NOP + + MOV &FOO,r10 + + BIC.W #8,SR ; Alias for DINT + BIS.W #8,SR ; Alias for EINT + NOP + + MOV &FOO,r10 + +;;; 5: Test EINT last insn in file + + NOP + EINT -- 2.7.4