aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2014-03-03 17:27:55 +0000
committerNick Clifton <nickc@redhat.com>2014-03-03 17:27:55 +0000
commit65d7bab5919338f2f41256e24c0609c91eaf0432 (patch)
tree009a19f6274a2dd338ee6e42603aed7e83d6e162 /gas
parentc1a3e85c37d0121efd395406ef3234b93e588a14 (diff)
downloadgdb-65d7bab5919338f2f41256e24c0609c91eaf0432.zip
gdb-65d7bab5919338f2f41256e24c0609c91eaf0432.tar.gz
gdb-65d7bab5919338f2f41256e24c0609c91eaf0432.tar.bz2
This patch enhances the MSP430 port of GAS so that, if requested, it will
generate warning messages about an instruction that changes the interrupt state not being followed by a NOP instruction. * config/msp430/msp430.c: Replace known mcu array with known msp430 ISA mcu name array. Accept any name for -mmcu option. Add -mz option to warn about missing NOP following an interrupt status change. (check_for_nop): New. (msp430_operands): Emit a warning, if requested, when an interrupt changing instruction is not followed by a NOP. * doc/c-msp430.c: Document -mz option. * gas/msp430/bad.d: Add -mz option. * gas/msp430/bad.s: Add more cases where warnings should be generated. * gas/msp430/bad.l: Add expected warning messages.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog12
-rw-r--r--gas/config/tc-msp430.c804
-rw-r--r--gas/config/tc-msp430.h1
-rw-r--r--gas/doc/c-msp430.texi27
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/msp430/bad.d1
-rw-r--r--gas/testsuite/gas/msp430/bad.l7
-rw-r--r--gas/testsuite/gas/msp430/bad.s18
8 files changed, 295 insertions, 582 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 7d9eea7..66d405f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@
+2014-03-03 Nick Clifton <nickc@redhat.com>
+
+ * config/msp430/msp430.c: Replace known mcu array with known
+ msp430 ISA mcu name array.
+ Accept any name for -mmcu option.
+ Add -mz option to warn about missing NOP following an interrupt
+ status change.
+ (check_for_nop): New.
+ (msp430_operands): Emit a warning, if requested, when an interrupt
+ changing instruction is not followed by a NOP.
+ * doc/c-msp430.c: Document -mz option.
+
2014-03-03 Alan Modra <amodra@gmail.com>
* config/bfin-lex-wrapper.c: Correct copyright date.
diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c
index a9aa0ea..948117c 100644
--- a/gas/config/tc-msp430.c
+++ b/gas/config/tc-msp430.c
@@ -264,487 +264,18 @@ typedef enum msp_isa
MSP_ISA_430Xv2
} msp_isa;
-struct mcu_type_s
-{
- char * name;
- msp_isa isa;
-};
-
-static struct mcu_type_s mcu_types[] =
-{
- {"msp430afe221", MSP_ISA_430},
- {"msp430afe222", MSP_ISA_430},
- {"msp430afe223", MSP_ISA_430},
- {"msp430afe231", MSP_ISA_430},
- {"msp430afe232", MSP_ISA_430},
- {"msp430afe233", MSP_ISA_430},
- {"msp430afe251", MSP_ISA_430},
- {"msp430afe252", MSP_ISA_430},
- {"msp430afe253", MSP_ISA_430},
- {"msp430c091", MSP_ISA_430},
- {"msp430c092", MSP_ISA_430},
- {"msp430c111", MSP_ISA_430},
- {"msp430c1111", MSP_ISA_430},
- {"msp430c112", MSP_ISA_430},
- {"msp430c1121", MSP_ISA_430},
- {"msp430e112", MSP_ISA_430},
- {"msp430c1331", MSP_ISA_430},
- {"msp430c1351", MSP_ISA_430},
- {"msp430c311s", MSP_ISA_430},
- {"msp430c312", MSP_ISA_430},
- {"msp430c313", MSP_ISA_430},
- {"msp430c314", MSP_ISA_430},
- {"msp430c315", MSP_ISA_430},
- {"msp430c323", MSP_ISA_430},
- {"msp430c325", MSP_ISA_430},
- {"msp430c336", MSP_ISA_430},
- {"msp430c337", MSP_ISA_430},
- {"msp430c412", MSP_ISA_430},
- {"msp430c413", MSP_ISA_430},
- {"msp430e313", MSP_ISA_430},
- {"msp430e315", MSP_ISA_430},
- {"msp430e325", MSP_ISA_430},
- {"msp430e337", MSP_ISA_430},
- {"msp430f110", MSP_ISA_430},
- {"msp430f1101", MSP_ISA_430},
- {"msp430f1101a", MSP_ISA_430},
- {"msp430f1111", MSP_ISA_430},
- {"msp430f1111a", MSP_ISA_430},
- {"msp430f112", MSP_ISA_430},
- {"msp430f1121", MSP_ISA_430},
- {"msp430f1121a", MSP_ISA_430},
- {"msp430f1122", MSP_ISA_430},
- {"msp430f1132", MSP_ISA_430},
- {"msp430f122", MSP_ISA_430},
- {"msp430f1222", MSP_ISA_430},
- {"msp430f123", MSP_ISA_430},
- {"msp430f1232", MSP_ISA_430},
- {"msp430f133", MSP_ISA_430},
- {"msp430f135", MSP_ISA_430},
- {"msp430f147", MSP_ISA_430},
- {"msp430f1471", MSP_ISA_430},
- {"msp430f148", MSP_ISA_430},
- {"msp430f1481", MSP_ISA_430},
- {"msp430f149", MSP_ISA_430},
- {"msp430f1491", MSP_ISA_430},
- {"msp430f155", MSP_ISA_430},
- {"msp430f156", MSP_ISA_430},
- {"msp430f157", MSP_ISA_430},
- {"msp430f1610", MSP_ISA_430},
- {"msp430f1611", MSP_ISA_430},
- {"msp430f1612", MSP_ISA_430},
- {"msp430f167", MSP_ISA_430},
- {"msp430f168", MSP_ISA_430},
- {"msp430f169", MSP_ISA_430},
- {"msp430f2001", MSP_ISA_430},
- {"msp430f2002", MSP_ISA_430},
- {"msp430f2003", MSP_ISA_430},
- {"msp430f2011", MSP_ISA_430},
- {"msp430f2012", MSP_ISA_430},
- {"msp430f2013", MSP_ISA_430},
- {"msp430f2101", MSP_ISA_430},
- {"msp430f2111", MSP_ISA_430},
- {"msp430f2112", MSP_ISA_430},
- {"msp430f2121", MSP_ISA_430},
- {"msp430f2122", MSP_ISA_430},
- {"msp430f2131", MSP_ISA_430},
- {"msp430f2132", MSP_ISA_430},
- {"msp430f2232", MSP_ISA_430},
- {"msp430f2234", MSP_ISA_430},
- {"msp430f2252", MSP_ISA_430},
- {"msp430f2254", MSP_ISA_430},
- {"msp430f2272", MSP_ISA_430},
- {"msp430f2274", MSP_ISA_430},
- {"msp430f233", MSP_ISA_430},
- {"msp430f2330", MSP_ISA_430},
- {"msp430f235", MSP_ISA_430},
- {"msp430f2350", MSP_ISA_430},
- {"msp430f2370", MSP_ISA_430},
- {"msp430f2410", MSP_ISA_430},
- {"msp430f247", MSP_ISA_430},
- {"msp430f2471", MSP_ISA_430},
- {"msp430f248", MSP_ISA_430},
- {"msp430f2481", MSP_ISA_430},
- {"msp430f249", MSP_ISA_430},
- {"msp430f2491", MSP_ISA_430},
- {"msp430f412", MSP_ISA_430},
- {"msp430f413", MSP_ISA_430},
- {"msp430f4132", MSP_ISA_430},
- {"msp430f415", MSP_ISA_430},
- {"msp430f4152", MSP_ISA_430},
- {"msp430f417", MSP_ISA_430},
- {"msp430f423", MSP_ISA_430},
- {"msp430f423a", MSP_ISA_430},
- {"msp430f425", MSP_ISA_430},
- {"msp430f4250", MSP_ISA_430},
- {"msp430f425a", MSP_ISA_430},
- {"msp430f4260", MSP_ISA_430},
- {"msp430f427", MSP_ISA_430},
- {"msp430f4270", MSP_ISA_430},
- {"msp430f427a", MSP_ISA_430},
- {"msp430f435", MSP_ISA_430},
- {"msp430f4351", MSP_ISA_430},
- {"msp430f436", MSP_ISA_430},
- {"msp430f4361", MSP_ISA_430},
- {"msp430f437", MSP_ISA_430},
- {"msp430f4371", MSP_ISA_430},
- {"msp430f438", MSP_ISA_430},
- {"msp430f439", MSP_ISA_430},
- {"msp430f447", MSP_ISA_430},
- {"msp430f448", MSP_ISA_430},
- {"msp430f4481", MSP_ISA_430},
- {"msp430f449", MSP_ISA_430},
- {"msp430f4491", MSP_ISA_430},
- {"msp430f477", MSP_ISA_430},
- {"msp430f478", MSP_ISA_430},
- {"msp430f4783", MSP_ISA_430},
- {"msp430f4784", MSP_ISA_430},
- {"msp430f479", MSP_ISA_430},
- {"msp430f4793", MSP_ISA_430},
- {"msp430f4794", MSP_ISA_430},
- {"msp430fe423", MSP_ISA_430},
- {"msp430fe4232", MSP_ISA_430},
- {"msp430fe423a", MSP_ISA_430},
- {"msp430fe4242", MSP_ISA_430},
- {"msp430fe425", MSP_ISA_430},
- {"msp430fe4252", MSP_ISA_430},
- {"msp430fe425a", MSP_ISA_430},
- {"msp430fe427", MSP_ISA_430},
- {"msp430fe4272", MSP_ISA_430},
- {"msp430fe427a", MSP_ISA_430},
- {"msp430fg4250", MSP_ISA_430},
- {"msp430fg4260", MSP_ISA_430},
- {"msp430fg4270", MSP_ISA_430},
- {"msp430fg437", MSP_ISA_430},
- {"msp430fg438", MSP_ISA_430},
- {"msp430fg439", MSP_ISA_430},
- {"msp430fg477", MSP_ISA_430},
- {"msp430fg478", MSP_ISA_430},
- {"msp430fg479", MSP_ISA_430},
- {"msp430fw423", MSP_ISA_430},
- {"msp430fw425", MSP_ISA_430},
- {"msp430fw427", MSP_ISA_430},
- {"msp430fw428", MSP_ISA_430},
- {"msp430fw429", MSP_ISA_430},
- {"msp430g2001", MSP_ISA_430},
- {"msp430g2101", MSP_ISA_430},
- {"msp430g2102", MSP_ISA_430},
- {"msp430g2111", MSP_ISA_430},
- {"msp430g2112", MSP_ISA_430},
- {"msp430g2113", MSP_ISA_430},
- {"msp430g2121", MSP_ISA_430},
- {"msp430g2131", MSP_ISA_430},
- {"msp430g2132", MSP_ISA_430},
- {"msp430g2152", MSP_ISA_430},
- {"msp430g2153", MSP_ISA_430},
- {"msp430g2201", MSP_ISA_430},
- {"msp430g2202", MSP_ISA_430},
- {"msp430g2203", MSP_ISA_430},
- {"msp430g2210", MSP_ISA_430},
- {"msp430g2211", MSP_ISA_430},
- {"msp430g2212", MSP_ISA_430},
- {"msp430g2213", MSP_ISA_430},
- {"msp430g2221", MSP_ISA_430},
- {"msp430g2230", MSP_ISA_430},
- {"msp430g2231", MSP_ISA_430},
- {"msp430g2232", MSP_ISA_430},
- {"msp430g2233", MSP_ISA_430},
- {"msp430g2252", MSP_ISA_430},
- {"msp430g2253", MSP_ISA_430},
- {"msp430g2302", MSP_ISA_430},
- {"msp430g2303", MSP_ISA_430},
- {"msp430g2312", MSP_ISA_430},
- {"msp430g2313", MSP_ISA_430},
- {"msp430g2332", MSP_ISA_430},
- {"msp430g2333", MSP_ISA_430},
- {"msp430g2352", MSP_ISA_430},
- {"msp430g2353", MSP_ISA_430},
- {"msp430g2402", MSP_ISA_430},
- {"msp430g2403", MSP_ISA_430},
- {"msp430g2412", MSP_ISA_430},
- {"msp430g2413", MSP_ISA_430},
- {"msp430g2432", MSP_ISA_430},
- {"msp430g2433", MSP_ISA_430},
- {"msp430g2444", MSP_ISA_430},
- {"msp430g2452", MSP_ISA_430},
- {"msp430g2453", MSP_ISA_430},
- {"msp430g2513", MSP_ISA_430},
- {"msp430g2533", MSP_ISA_430},
- {"msp430g2544", MSP_ISA_430},
- {"msp430g2553", MSP_ISA_430},
- {"msp430g2744", MSP_ISA_430},
- {"msp430g2755", MSP_ISA_430},
- {"msp430g2855", MSP_ISA_430},
- {"msp430g2955", MSP_ISA_430},
- {"msp430l092", MSP_ISA_430},
- {"msp430p112", MSP_ISA_430},
- {"msp430p313", MSP_ISA_430},
- {"msp430p315", MSP_ISA_430},
- {"msp430p315s", MSP_ISA_430},
- {"msp430p325", MSP_ISA_430},
- {"msp430p337", MSP_ISA_430},
- {"msp430tch5e", MSP_ISA_430},
-
- /* NB/ This section of the list should be kept in sync with the ones in:
- gcc/config/msp430/t-msp430
- gcc/config/msp430/msp430.c */
-
- {"msp430cg4616", MSP_ISA_430X},
- {"msp430cg4617", MSP_ISA_430X},
- {"msp430cg4618", MSP_ISA_430X},
- {"msp430cg4619", MSP_ISA_430X},
- {"msp430f2416", MSP_ISA_430X},
- {"msp430f2417", MSP_ISA_430X},
- {"msp430f2418", MSP_ISA_430X},
- {"msp430f2419", MSP_ISA_430X},
- {"msp430f2616", MSP_ISA_430X},
- {"msp430f2617", MSP_ISA_430X},
- {"msp430f2618", MSP_ISA_430X},
- {"msp430f2619", MSP_ISA_430X},
- {"msp430f47126", MSP_ISA_430X},
- {"msp430f47127", MSP_ISA_430X},
- {"msp430f47163", MSP_ISA_430X},
- {"msp430f47173", MSP_ISA_430X},
- {"msp430f47183", MSP_ISA_430X},
- {"msp430f47193", MSP_ISA_430X},
- {"msp430f47166", MSP_ISA_430X},
- {"msp430f47176", MSP_ISA_430X},
- {"msp430f47186", MSP_ISA_430X},
- {"msp430f47196", MSP_ISA_430X},
- {"msp430f47167", MSP_ISA_430X},
- {"msp430f47177", MSP_ISA_430X},
- {"msp430f47187", MSP_ISA_430X},
- {"msp430f47197", MSP_ISA_430X},
- {"msp430f46161", MSP_ISA_430X},
- {"msp430f46171", MSP_ISA_430X},
- {"msp430f46181", MSP_ISA_430X},
- {"msp430f46191", MSP_ISA_430X},
- {"msp430f4616", MSP_ISA_430X},
- {"msp430f4617", MSP_ISA_430X},
- {"msp430f4618", MSP_ISA_430X},
- {"msp430f4619", MSP_ISA_430X},
- {"msp430fg4616", MSP_ISA_430X},
- {"msp430fg4617", MSP_ISA_430X},
- {"msp430fg4618", MSP_ISA_430X},
- {"msp430fg4619", MSP_ISA_430X},
-
- {"msp430x241x", MSP_ISA_430X},
- {"msp430x26x", MSP_ISA_430X},
- {"msp430x461x1", MSP_ISA_430X},
- {"msp430x46x", MSP_ISA_430X},
- {"msp430x471x3", MSP_ISA_430X},
- {"msp430x471x6", MSP_ISA_430X},
- {"msp430x471x7", MSP_ISA_430X},
- {"msp430xg46x", MSP_ISA_430X},
-
- {"msp430f5418", MSP_ISA_430Xv2},
- {"msp430f5419", MSP_ISA_430Xv2},
- {"msp430f5435", MSP_ISA_430Xv2},
- {"msp430f5436", MSP_ISA_430Xv2},
- {"msp430f5437", MSP_ISA_430Xv2},
- {"msp430f5438", MSP_ISA_430Xv2},
- {"msp430f5418a", MSP_ISA_430Xv2},
- {"msp430f5419a", MSP_ISA_430Xv2},
- {"msp430f5435a", MSP_ISA_430Xv2},
- {"msp430f5436a", MSP_ISA_430Xv2},
- {"msp430f5437a", MSP_ISA_430Xv2},
- {"msp430f5438a", MSP_ISA_430Xv2},
- {"msp430f5212", MSP_ISA_430Xv2},
- {"msp430f5213", MSP_ISA_430Xv2},
- {"msp430f5214", MSP_ISA_430Xv2},
- {"msp430f5217", MSP_ISA_430Xv2},
- {"msp430f5218", MSP_ISA_430Xv2},
- {"msp430f5219", MSP_ISA_430Xv2},
- {"msp430f5222", MSP_ISA_430Xv2},
- {"msp430f5223", MSP_ISA_430Xv2},
- {"msp430f5224", MSP_ISA_430Xv2},
- {"msp430f5227", MSP_ISA_430Xv2},
- {"msp430f5228", MSP_ISA_430Xv2},
- {"msp430f5229", MSP_ISA_430Xv2},
- {"msp430f5304", MSP_ISA_430Xv2},
- {"msp430f5308", MSP_ISA_430Xv2},
- {"msp430f5309", MSP_ISA_430Xv2},
- {"msp430f5310", MSP_ISA_430Xv2},
- {"msp430f5340", MSP_ISA_430Xv2},
- {"msp430f5341", MSP_ISA_430Xv2},
- {"msp430f5342", MSP_ISA_430Xv2},
- {"msp430f5324", MSP_ISA_430Xv2},
- {"msp430f5325", MSP_ISA_430Xv2},
- {"msp430f5326", MSP_ISA_430Xv2},
- {"msp430f5327", MSP_ISA_430Xv2},
- {"msp430f5328", MSP_ISA_430Xv2},
- {"msp430f5329", MSP_ISA_430Xv2},
- {"msp430f5500", MSP_ISA_430Xv2},
- {"msp430f5501", MSP_ISA_430Xv2},
- {"msp430f5502", MSP_ISA_430Xv2},
- {"msp430f5503", MSP_ISA_430Xv2},
- {"msp430f5504", MSP_ISA_430Xv2},
- {"msp430f5505", MSP_ISA_430Xv2},
- {"msp430f5506", MSP_ISA_430Xv2},
- {"msp430f5507", MSP_ISA_430Xv2},
- {"msp430f5508", MSP_ISA_430Xv2},
- {"msp430f5509", MSP_ISA_430Xv2},
- {"msp430f5510", MSP_ISA_430Xv2},
- {"msp430f5513", MSP_ISA_430Xv2},
- {"msp430f5514", MSP_ISA_430Xv2},
- {"msp430f5515", MSP_ISA_430Xv2},
- {"msp430f5517", MSP_ISA_430Xv2},
- {"msp430f5519", MSP_ISA_430Xv2},
- {"msp430f5521", MSP_ISA_430Xv2},
- {"msp430f5522", MSP_ISA_430Xv2},
- {"msp430f5524", MSP_ISA_430Xv2},
- {"msp430f5525", MSP_ISA_430Xv2},
- {"msp430f5526", MSP_ISA_430Xv2},
- {"msp430f5527", MSP_ISA_430Xv2},
- {"msp430f5528", MSP_ISA_430Xv2},
- {"msp430f5529", MSP_ISA_430Xv2},
- {"cc430f5133", MSP_ISA_430Xv2},
- {"cc430f5135", MSP_ISA_430Xv2},
- {"cc430f5137", MSP_ISA_430Xv2},
- {"cc430f6125", MSP_ISA_430Xv2},
- {"cc430f6126", MSP_ISA_430Xv2},
- {"cc430f6127", MSP_ISA_430Xv2},
- {"cc430f6135", MSP_ISA_430Xv2},
- {"cc430f6137", MSP_ISA_430Xv2},
- {"cc430f5123", MSP_ISA_430Xv2},
- {"cc430f5125", MSP_ISA_430Xv2},
- {"cc430f5143", MSP_ISA_430Xv2},
- {"cc430f5145", MSP_ISA_430Xv2},
- {"cc430f5147", MSP_ISA_430Xv2},
- {"cc430f6143", MSP_ISA_430Xv2},
- {"cc430f6145", MSP_ISA_430Xv2},
- {"cc430f6147", MSP_ISA_430Xv2},
- {"msp430f5333", MSP_ISA_430Xv2},
- {"msp430f5335", MSP_ISA_430Xv2},
- {"msp430f5336", MSP_ISA_430Xv2},
- {"msp430f5338", MSP_ISA_430Xv2},
- {"msp430f5630", MSP_ISA_430Xv2},
- {"msp430f5631", MSP_ISA_430Xv2},
- {"msp430f5632", MSP_ISA_430Xv2},
- {"msp430f5633", MSP_ISA_430Xv2},
- {"msp430f5634", MSP_ISA_430Xv2},
- {"msp430f5635", MSP_ISA_430Xv2},
- {"msp430f5636", MSP_ISA_430Xv2},
- {"msp430f5637", MSP_ISA_430Xv2},
- {"msp430f5638", MSP_ISA_430Xv2},
- {"msp430f6433", MSP_ISA_430Xv2},
- {"msp430f6435", MSP_ISA_430Xv2},
- {"msp430f6436", MSP_ISA_430Xv2},
- {"msp430f6438", MSP_ISA_430Xv2},
- {"msp430f6630", MSP_ISA_430Xv2},
- {"msp430f6631", MSP_ISA_430Xv2},
- {"msp430f6632", MSP_ISA_430Xv2},
- {"msp430f6633", MSP_ISA_430Xv2},
- {"msp430f6634", MSP_ISA_430Xv2},
- {"msp430f6635", MSP_ISA_430Xv2},
- {"msp430f6636", MSP_ISA_430Xv2},
- {"msp430f6637", MSP_ISA_430Xv2},
- {"msp430f6638", MSP_ISA_430Xv2},
- {"msp430f5358", MSP_ISA_430Xv2},
- {"msp430f5359", MSP_ISA_430Xv2},
- {"msp430f5658", MSP_ISA_430Xv2},
- {"msp430f5659", MSP_ISA_430Xv2},
- {"msp430f6458", MSP_ISA_430Xv2},
- {"msp430f6459", MSP_ISA_430Xv2},
- {"msp430f6658", MSP_ISA_430Xv2},
- {"msp430f6659", MSP_ISA_430Xv2},
- {"msp430f5131", MSP_ISA_430Xv2},
- {"msp430f5151", MSP_ISA_430Xv2},
- {"msp430f5171", MSP_ISA_430Xv2},
- {"msp430f5132", MSP_ISA_430Xv2},
- {"msp430f5152", MSP_ISA_430Xv2},
- {"msp430f5172", MSP_ISA_430Xv2},
- {"msp430f6720", MSP_ISA_430Xv2},
- {"msp430f6721", MSP_ISA_430Xv2},
- {"msp430f6723", MSP_ISA_430Xv2},
- {"msp430f6724", MSP_ISA_430Xv2},
- {"msp430f6725", MSP_ISA_430Xv2},
- {"msp430f6726", MSP_ISA_430Xv2},
- {"msp430f6730", MSP_ISA_430Xv2},
- {"msp430f6731", MSP_ISA_430Xv2},
- {"msp430f6733", MSP_ISA_430Xv2},
- {"msp430f6734", MSP_ISA_430Xv2},
- {"msp430f6735", MSP_ISA_430Xv2},
- {"msp430f6736", MSP_ISA_430Xv2},
- {"msp430f67451", MSP_ISA_430Xv2},
- {"msp430f67651", MSP_ISA_430Xv2},
- {"msp430f67751", MSP_ISA_430Xv2},
- {"msp430f67461", MSP_ISA_430Xv2},
- {"msp430f67661", MSP_ISA_430Xv2},
- {"msp430f67761", MSP_ISA_430Xv2},
- {"msp430f67471", MSP_ISA_430Xv2},
- {"msp430f67671", MSP_ISA_430Xv2},
- {"msp430f67771", MSP_ISA_430Xv2},
- {"msp430f67481", MSP_ISA_430Xv2},
- {"msp430f67681", MSP_ISA_430Xv2},
- {"msp430f67781", MSP_ISA_430Xv2},
- {"msp430f67491", MSP_ISA_430Xv2},
- {"msp430f67691", MSP_ISA_430Xv2},
- {"msp430f67791", MSP_ISA_430Xv2},
- {"msp430f6745", MSP_ISA_430Xv2},
- {"msp430f6765", MSP_ISA_430Xv2},
- {"msp430f6775", MSP_ISA_430Xv2},
- {"msp430f6746", MSP_ISA_430Xv2},
- {"msp430f6766", MSP_ISA_430Xv2},
- {"msp430f6776", MSP_ISA_430Xv2},
- {"msp430f6747", MSP_ISA_430Xv2},
- {"msp430f6767", MSP_ISA_430Xv2},
- {"msp430f6777", MSP_ISA_430Xv2},
- {"msp430f6748", MSP_ISA_430Xv2},
- {"msp430f6768", MSP_ISA_430Xv2},
- {"msp430f6778", MSP_ISA_430Xv2},
- {"msp430f6749", MSP_ISA_430Xv2},
- {"msp430f6769", MSP_ISA_430Xv2},
- {"msp430f6779", MSP_ISA_430Xv2},
- {"msp430fr5720", MSP_ISA_430Xv2},
- {"msp430fr5721", MSP_ISA_430Xv2},
- {"msp430fr5722", MSP_ISA_430Xv2},
- {"msp430fr5723", MSP_ISA_430Xv2},
- {"msp430fr5724", MSP_ISA_430Xv2},
- {"msp430fr5725", MSP_ISA_430Xv2},
- {"msp430fr5726", MSP_ISA_430Xv2},
- {"msp430fr5727", MSP_ISA_430Xv2},
- {"msp430fr5728", MSP_ISA_430Xv2},
- {"msp430fr5729", MSP_ISA_430Xv2},
- {"msp430fr5730", MSP_ISA_430Xv2},
- {"msp430fr5731", MSP_ISA_430Xv2},
- {"msp430fr5732", MSP_ISA_430Xv2},
- {"msp430fr5733", MSP_ISA_430Xv2},
- {"msp430fr5734", MSP_ISA_430Xv2},
- {"msp430fr5735", MSP_ISA_430Xv2},
- {"msp430fr5736", MSP_ISA_430Xv2},
- {"msp430fr5737", MSP_ISA_430Xv2},
- {"msp430fr5738", MSP_ISA_430Xv2},
- {"msp430fr5739", MSP_ISA_430Xv2},
- {"msp430bt5190", MSP_ISA_430Xv2},
- {"msp430fr5949", MSP_ISA_430Xv2},
- {"msp430fr5969", MSP_ISA_430Xv2},
- {"msp430sl5438a", MSP_ISA_430Xv2},
-
- /* Generic names. */
- {"msp430", MSP_ISA_430},
- {"msp430X", MSP_ISA_430X},
- {"msp430Xv2", MSP_ISA_430Xv2},
-
- {NULL, 0}
-};
-
-static struct mcu_type_s default_mcu = { "msp430x11", MSP_ISA_430 };
-static struct mcu_type_s msp430x_mcu = { "msp430x", MSP_ISA_430X };
-static struct mcu_type_s msp430xv2_mcu = { "msp430xv2", MSP_ISA_430Xv2 };
-
-static struct mcu_type_s * msp430_mcu = & default_mcu;
+static enum msp_isa selected_isa = MSP_ISA_430Xv2;
static inline bfd_boolean
target_is_430x (void)
{
- return msp430_mcu->isa >= MSP_ISA_430X;
+ return selected_isa >= MSP_ISA_430X;
}
static inline bfd_boolean
target_is_430xv2 (void)
{
- return msp430_mcu->isa == MSP_ISA_430Xv2;
+ return selected_isa == MSP_ISA_430Xv2;
}
/* Generate a 16-bit relocation.
@@ -1133,9 +664,12 @@ extract_word (char * from, char * to, int limit)
#define OPTION_POLYMORPHS 'P'
#define OPTION_LARGE 'l'
static bfd_boolean large_model = FALSE;
-#define OPTION_INTR_NOPS 'n'
#define OPTION_NO_INTR_NOPS 'N'
+#define OPTION_INTR_NOPS 'n'
static bfd_boolean gen_interrupt_nops = FALSE;
+#define OPTION_WARN_INTR_NOPS 'z'
+#define OPTION_NO_WARN_INTR_NOPS 'Z'
+static bfd_boolean warn_interrupt_nops = TRUE;
#define OPTION_MCPU 'c'
#define OPTION_MOVE_DATA 'd'
static bfd_boolean move_data = FALSE;
@@ -1152,43 +686,106 @@ msp430_set_arch (int option)
target_is_430x () ? bfd_mach_msp430x : bfd_mach_msp11);
}
+/* This is the full list of MCU names that are known to only
+ support the 430 ISA. */
+static const char * msp430_mcu_names [] =
+{
+"msp430afe221", "msp430afe222", "msp430afe223", "msp430afe231",
+"msp430afe232", "msp430afe233", "msp430afe251", "msp430afe252",
+"msp430afe253", "msp430c091", "msp430c092", "msp430c111",
+"msp430c1111", "msp430c112", "msp430c1121", "msp430c1331",
+"msp430c1351", "msp430c311s", "msp430c312", "msp430c313",
+"msp430c314", "msp430c315", "msp430c323", "msp430c325",
+"msp430c336", "msp430c337", "msp430c412", "msp430c413",
+"msp430e112", "msp430e313", "msp430e315", "msp430e325",
+"msp430e337", "msp430f110", "msp430f1101", "msp430f1101a",
+"msp430f1111", "msp430f1111a", "msp430f112", "msp430f1121",
+"msp430f1121a", "msp430f1122", "msp430f1132", "msp430f122",
+"msp430f1222", "msp430f123", "msp430f1232", "msp430f133",
+"msp430f135", "msp430f147", "msp430f1471", "msp430f148",
+"msp430f1481", "msp430f149", "msp430f1491", "msp430f155",
+"msp430f156", "msp430f157", "msp430f1610", "msp430f1611",
+"msp430f1612", "msp430f167", "msp430f168", "msp430f169",
+"msp430f2001", "msp430f2002", "msp430f2003", "msp430f2011",
+"msp430f2012", "msp430f2013", "msp430f2101", "msp430f2111",
+"msp430f2112", "msp430f2121", "msp430f2122", "msp430f2131",
+"msp430f2132", "msp430f2232", "msp430f2234", "msp430f2252",
+"msp430f2254", "msp430f2272", "msp430f2274", "msp430f233",
+"msp430f2330", "msp430f235", "msp430f2350", "msp430f2370",
+"msp430f2410", "msp430f247", "msp430f2471", "msp430f248",
+"msp430f2481", "msp430f249", "msp430f2491", "msp430f412",
+"msp430f413", "msp430f4132", "msp430f415", "msp430f4152",
+"msp430f417", "msp430f423", "msp430f423a", "msp430f425",
+"msp430f4250", "msp430f425a", "msp430f4260", "msp430f427",
+"msp430f4270", "msp430f427a", "msp430f435", "msp430f4351",
+"msp430f436", "msp430f4361", "msp430f437", "msp430f4371",
+"msp430f438", "msp430f439", "msp430f447", "msp430f448",
+"msp430f4481", "msp430f449", "msp430f4491", "msp430f477",
+"msp430f478", "msp430f4783", "msp430f4784", "msp430f479",
+"msp430f4793", "msp430f4794", "msp430fe423", "msp430fe4232",
+"msp430fe423a", "msp430fe4242", "msp430fe425", "msp430fe4252",
+"msp430fe425a", "msp430fe427", "msp430fe4272", "msp430fe427a",
+"msp430fg4250", "msp430fg4260", "msp430fg4270", "msp430fg437",
+"msp430fg438", "msp430fg439", "msp430fg477", "msp430fg478",
+"msp430fg479", "msp430fw423", "msp430fw425", "msp430fw427",
+"msp430fw428", "msp430fw429", "msp430g2001", "msp430g2101",
+"msp430g2102", "msp430g2111", "msp430g2112", "msp430g2113",
+"msp430g2121", "msp430g2131", "msp430g2132", "msp430g2152",
+"msp430g2153", "msp430g2201", "msp430g2202", "msp430g2203",
+"msp430g2210", "msp430g2211", "msp430g2212", "msp430g2213",
+"msp430g2221", "msp430g2230", "msp430g2231", "msp430g2232",
+"msp430g2233", "msp430g2252", "msp430g2253", "msp430g2302",
+"msp430g2303", "msp430g2312", "msp430g2313", "msp430g2332",
+"msp430g2333", "msp430g2352", "msp430g2353", "msp430g2402",
+"msp430g2403", "msp430g2412", "msp430g2413", "msp430g2432",
+"msp430g2433", "msp430g2444", "msp430g2452", "msp430g2453",
+"msp430g2513", "msp430g2533", "msp430g2544", "msp430g2553",
+"msp430g2744", "msp430g2755", "msp430g2855", "msp430g2955",
+"msp430i2020", "msp430i2021", "msp430i2030", "msp430i2031",
+"msp430i2040", "msp430i2041", "msp430l092", "msp430p112",
+"msp430p313", "msp430p315", "msp430p315s", "msp430p325",
+"msp430p337", "msp430tch5e"
+};
+
int
md_parse_option (int c, char * arg)
{
- int i;
-
switch (c)
{
case OPTION_MMCU:
if (arg == NULL)
as_fatal (_("MCU option requires a name\n"));
- for (i = 0; mcu_types[i].name; ++i)
- if (strcasecmp (mcu_types[i].name, arg) == 0)
- break;
-
- if (mcu_types[i].name != NULL)
+ if (strcasecmp ("msp430", arg) == 0)
+ selected_isa = MSP_ISA_430;
+ else if (strcasecmp ("msp430xv2", arg) == 0)
+ selected_isa = MSP_ISA_430Xv2;
+ else if (strcasecmp ("msp430x", arg) == 0)
+ selected_isa = MSP_ISA_430X;
+ else
{
- /* Allow switching to the same or a lesser architecture. */
- if (msp430_mcu == &default_mcu || msp430_mcu->isa >= mcu_types[i].isa)
- msp430_mcu = mcu_types + i;
- else
- as_fatal (_("redefinition of mcu type '%s' to '%s'"),
- msp430_mcu->name, mcu_types[i].name);
+ int i;
+
+ for (i = sizeof msp430_mcu_names / sizeof msp430_mcu_names[0]; i--;)
+ if (strcasecmp (msp430_mcu_names[i], arg) == 0)
+ {
+ selected_isa = MSP_ISA_430;
+ break;
+ }
}
/* It is not an error if we do not match the MCU name. */
return 1;
-
+
case OPTION_MCPU:
if (strcmp (arg, "430") == 0
|| strcasecmp (arg, "msp430") == 0)
- msp430_mcu = & default_mcu;
+ selected_isa = MSP_ISA_430;
else if (strcasecmp (arg, "430x") == 0
|| strcasecmp (arg, "msp430x") == 0)
- msp430_mcu = & msp430x_mcu;
+ selected_isa = MSP_ISA_430X;
else if (strcasecmp (arg, "430xv2") == 0
|| strcasecmp (arg, "msp430xv2") == 0)
- msp430_mcu = & msp430xv2_mcu;
+ selected_isa = MSP_ISA_430Xv2;
else
as_fatal (_("unrecognised argument to -mcpu option '%s'"), arg);
return 1;
@@ -1212,6 +809,13 @@ md_parse_option (int c, char * arg)
gen_interrupt_nops = TRUE;
return 1;
+ case OPTION_WARN_INTR_NOPS:
+ warn_interrupt_nops = TRUE;
+ return 1;
+ case OPTION_NO_WARN_INTR_NOPS:
+ warn_interrupt_nops = FALSE;
+ return 1;
+
case OPTION_MOVE_DATA:
move_data = TRUE;
return 1;
@@ -1309,7 +913,7 @@ const pseudo_typeS md_pseudo_table[] =
{NULL, NULL, 0}
};
-const char *md_shortopts = "mm:,mP,mQ,ml,mN";
+const char *md_shortopts = "mm:,mP,mQ,ml,mN,mn,mz,mZ";
struct option md_longopts[] =
{
@@ -1320,6 +924,8 @@ struct option md_longopts[] =
{"ml", no_argument, NULL, OPTION_LARGE},
{"mN", no_argument, NULL, OPTION_NO_INTR_NOPS},
{"mn", no_argument, NULL, OPTION_INTR_NOPS},
+ {"mZ", no_argument, NULL, OPTION_NO_WARN_INTR_NOPS},
+ {"mz", no_argument, NULL, OPTION_WARN_INTR_NOPS},
{"md", no_argument, NULL, OPTION_MOVE_DATA},
{NULL, no_argument, NULL, 0}
};
@@ -1339,9 +945,13 @@ md_show_usage (FILE * stream)
fprintf (stream,
_(" -ml - enable large code model\n"));
fprintf (stream,
- _(" -mN - disable generation of NOP after changing interrupts\n"));
+ _(" -mN - do not insert NOPs after changing interrupts (default)\n"));
fprintf (stream,
- _(" -mn - enable generation of NOP after changing interrupts\n"));
+ _(" -mn - insert a NOP after changing interrupts\n"));
+ fprintf (stream,
+ _(" -mZ - do not warn about missing NOPs after changing interrupts\n"));
+ fprintf (stream,
+ _(" -mz - warn about missing NOPs after changing interrupts (default)\n"));
fprintf (stream,
_(" -md - Force copying of data from ROM to RAM at startup\n"));
}
@@ -1483,7 +1093,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
op->reg = 0; /* Reg PC. */
op->am = 3;
- op->ol = 1; /* Immediate will follow an instruction. */
+ op->ol = 1; /* Immediate will follow an instruction. */
__tl = h + 1 + rval;
op->mode = OP_EXP;
@@ -1603,6 +1213,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
else if (op->exp.X_op == O_big)
{
short x;
+
if (vshift != -1)
{
op->exp.X_op = O_constant;
@@ -1744,6 +1355,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
as_bad (_("cannot use indirect addressing with the PC"));
return 1;
}
+
return 0;
}
@@ -1902,7 +1514,6 @@ msp430_dstoperand (struct msp430_operand_s * op,
return 0;
}
-
/* Attempt to encode a MOVA instruction with the given operands.
Returns the length of the encoded instruction if successful
or 0 upon failure. If the encoding fails, an error message
@@ -2162,6 +1773,8 @@ try_encode_mova (bfd_boolean imm_op,
return 0;
}
+static bfd_boolean check_for_nop = FALSE;
+
#define is_opcode(NAME) (strcmp (opcode->name, NAME) == 0)
/* Parse instruction operands.
@@ -2187,6 +1800,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
const char * error_message;
static signed int repeat_count = 0;
bfd_boolean fix_emitted;
+ bfd_boolean nop_check_needed = FALSE;
/* Opcode is the one from opcodes table
line contains something like
@@ -2319,12 +1933,40 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
repeat_count = 0;
}
+ if (check_for_nop && is_opcode ("nop"))
+ check_for_nop = FALSE;
+
switch (fmt)
{
case 0: /* Emulated. */
switch (opcode->insn_opnumb)
{
case 0:
+ if (is_opcode ("eint") || is_opcode ("dint"))
+ {
+ if (check_for_nop)
+ {
+ if (warn_interrupt_nops)
+ {
+ if (gen_interrupt_nops)
+ as_warn (_("NOP inserted between two instructions that change interrupt state"));
+ else
+ as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
+ }
+
+ if (gen_interrupt_nops)
+ {
+ /* Emit a NOP between interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+ }
+
+ nop_check_needed = TRUE;
+ }
+
/* Set/clear bits instructions. */
if (extended_op)
{
@@ -2333,25 +1975,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
/* Emit the extension word. */
insn_length += 2;
- frag = frag_more (insn_length);
+ frag = frag_more (2);
bfd_putl16 (extended, frag);
}
insn_length += 2;
- frag = frag_more (insn_length);
+ frag = frag_more (2);
bfd_putl16 ((bfd_vma) bin, frag);
-
- if (gen_interrupt_nops
- && (is_opcode ("eint") || is_opcode ("dint")))
- {
- /* Emit a NOP following interrupt enable/disable.
- See 1.3.4.1 of the MSP430x5xx User Guide. */
- insn_length += 2;
- frag = frag_more (2);
- as_warn (_("a NOP instruction has been inserted after %s"),
- opcode->name);
- bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
- }
dwarf2_emit_insn (insn_length);
break;
@@ -2362,9 +1992,37 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (res)
break;
+ bin |= (op1.reg | (op1.am << 7));
+
+ if (is_opcode ("clr") && bin == 0x4302 /* CLR R2*/)
+ {
+ if (check_for_nop)
+ {
+ if (warn_interrupt_nops)
+ {
+ if (gen_interrupt_nops)
+ as_warn (_("NOP inserted between two instructions that change interrupt state"));
+ else
+ as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
+ }
+
+ if (gen_interrupt_nops)
+ {
+ /* Emit a NOP between interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+ }
+
+ nop_check_needed = TRUE;
+ }
+
/* Compute the entire instruction length, in bytes. */
- insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
- frag = frag_more (insn_length);
+ op_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
+ insn_length += op_length;
+ frag = frag_more (op_length);
where = frag - frag_now->fr_literal;
if (extended_op)
@@ -2397,7 +2055,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
where += 2;
}
- bin |= (op1.reg | (op1.am << 7));
bfd_putl16 ((bfd_vma) bin, frag);
frag += 2;
where += 2;
@@ -2424,19 +2081,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
}
- if (gen_interrupt_nops
- && is_opcode ("clr")
- && bin == 0x4302 /* CLR R2*/)
- {
- /* Emit a NOP following interrupt enable/disable.
- See 1.3.4.1 of the MSP430x5xx User Guide. */
- insn_length += 2;
- frag = frag_more (2);
- bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
- as_warn (_("a NOP instruction has been inserted after %s"),
- opcode->name);
- }
-
dwarf2_emit_insn (insn_length);
break;
@@ -2464,7 +2108,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
|| is_opcode ("rlc")))
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
if (extended_op)
@@ -2571,7 +2215,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended_op)
{
as_bad ("Internal error: state 0/3 not coded for extended instructions");
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2675,7 +2319,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (op1.ol != 1)
{
as_bad ("Internal error: unexpected CALLA instruction length: %d\n", op1.ol);
- return 0;
+ break;
}
bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
@@ -2700,21 +2344,21 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (*l1 != '#')
{
as_bad (_("expected #n as first argument of %s"), opcode->name);
- return 0;
+ break;
}
parse_exp (l1 + 1, &(op1.exp));
if (op1.exp.X_op != O_constant)
{
as_bad (_("expected constant expression for first argument of %s"),
opcode->name);
- return 0;
+ break;
}
if ((reg = check_reg (l2)) == -1)
{
as_bad (_("expected register as second argument of %s"),
opcode->name);
- return 0;
+ break;
}
op_length = 2;
@@ -2732,17 +2376,17 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (reg - n + 1 < 0)
{
as_bad (_("Too many registers popped"));
- return 0;
+ break;
}
- /* CPU21 parts cannot use POPM to restore the SR register. */
+ /* CPU21 errata: cannot use POPM to restore the SR register. */
if (target_is_430xv2 ()
&& (reg - n + 1 < 3)
&& reg >= 2
&& is_opcode ("popm"))
{
as_bad (_("Cannot use POPM to restore the SR register"));
- return 0;
+ break;
}
bin |= (reg - n + 1);
@@ -2762,7 +2406,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended & 0xff)
{
as_bad (_("repeat count cannot be used with %s"), opcode->name);
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2771,34 +2415,34 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (*l1 != '#')
{
as_bad (_("expected #n as first argument of %s"), opcode->name);
- return 0;
+ break;
}
parse_exp (l1 + 1, &(op1.exp));
if (op1.exp.X_op != O_constant)
{
as_bad (_("expected constant expression for first argument of %s"),
opcode->name);
- return 0;
+ break;
}
n = op1.exp.X_add_number;
if (n > 4 || n < 1)
{
as_bad (_("expected first argument of %s to be in the range 1-4"),
opcode->name);
- return 0;
+ break;
}
if ((reg = check_reg (l2)) == -1)
{
as_bad (_("expected register as second argument of %s"),
opcode->name);
- return 0;
+ break;
}
if (target_is_430xv2 () && reg == 0)
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
op_length = 2;
@@ -2824,7 +2468,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended & 0xff)
{
as_bad (_("repeat count cannot be used with %s"), opcode->name);
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2832,13 +2476,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected register as argument of %s"),
opcode->name);
- return 0;
+ break;
}
if (target_is_430xv2 () && reg == 0)
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
if (byte_op)
@@ -2883,7 +2527,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (extended & 0xff)
{
as_bad (_("repeat count cannot be used with %s"), opcode->name);
- return 0;
+ break;
}
line = extract_operand (line, l1, sizeof (l1));
@@ -2902,7 +2546,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected value of first argument of %s to fit into 20-bits"),
opcode->name);
- return 0;
+ break;
}
bin |= ((n >> 16) & 0xf) << 8;
@@ -2921,7 +2565,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected register name or constant as first argument of %s"),
opcode->name);
- return 0;
+ break;
}
bin |= (n << 8) | (1 << 6);
@@ -2932,7 +2576,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("expected register as second argument of %s"),
opcode->name);
- return 0;
+ break;
}
frag = frag_more (op_length);
@@ -2995,7 +2639,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
& error_message)) == 0)
{
as_bad (error_message, opcode->name);
- return 0;
+ break;
}
dwarf2_emit_insn (op_length);
break;
@@ -3009,13 +2653,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
if (op1.exp.X_op != O_constant)
{
as_bad (_("expected constant value as argument to RPT"));
- return 0;
+ break;
}
if (op1.exp.X_add_number < 1
|| op1.exp.X_add_number > (1 << 4))
{
as_bad (_("expected constant in the range 2..16"));
- return 0;
+ break;
}
/* We silently accept and ignore a repeat count of 1. */
@@ -3036,7 +2680,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
else
{
as_bad (_("expected constant or register name as argument to RPT insn"));
- return 0;
+ break;
}
}
break;
@@ -3071,14 +2715,43 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
}
+ bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
+
+ if ( (is_opcode ("bic") && bin == 0xc232)
+ || (is_opcode ("bis") && bin == 0xd232)
+ || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2))
+ {
+ if (check_for_nop)
+ {
+ if (warn_interrupt_nops)
+ {
+ if (gen_interrupt_nops)
+ as_warn (_("NOP inserted between two instructions that change interrupt state"));
+ else
+ as_warn (_("a NOP might be needed here because of successive changes in interrupt state"));
+ }
+
+ if (gen_interrupt_nops)
+ {
+ /* Emit a NOP between interrupt enable/disable.
+ See 1.3.4.1 of the MSP430x5xx User Guide. */
+ insn_length += 2;
+ frag = frag_more (2);
+ bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
+ }
+ }
+
+ nop_check_needed = TRUE;
+ }
+
/* Compute the entire length of the instruction in bytes. */
- insn_length =
- (extended_op ? 2 : 0) /* The extension word. */
+ op_length = (extended_op ? 2 : 0) /* The extension word. */
+ 2 /* The opcode */
+ (2 * op1.ol) /* The first operand. */
+ (2 * op2.ol); /* The second operand. */
- frag = frag_more (insn_length);
+ insn_length += op_length;
+ frag = frag_more (op_length);
where = frag - frag_now->fr_literal;
if (extended_op)
@@ -3128,7 +2801,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
frag += 2;
}
- bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7));
bfd_putl16 ((bfd_vma) bin, frag);
where += 2;
frag += 2;
@@ -3180,20 +2852,6 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
}
- if (gen_interrupt_nops
- && ( (is_opcode ("bic") && bin == 0xc232)
- || (is_opcode ("bis") && bin == 0xd232)
- || (is_opcode ("mov") && op2.mode == OP_REG && op2.reg == 2)))
- {
- /* Emit a NOP following interrupt enable/disable.
- See 1.3.4.1 of the MSP430x5xx User Guide. */
- insn_length += 2;
- frag = frag_more (2);
- bfd_putl16 ((bfd_vma) 0x4303 /* NOP */, frag);
- as_warn (_("a NOP instruction has been inserted after %s"),
- opcode->name);
- }
-
dwarf2_emit_insn (insn_length);
break;
@@ -3223,7 +2881,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
|| is_opcode ("rrc")))
{
as_bad (_("%s: attempt to rotate the PC register"), opcode->name);
- return 0;
+ break;
}
insn_length = (extended_op ? 2 : 0) + 2 + (op1.ol * 2);
@@ -3242,7 +2900,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
{
as_bad (_("%s instruction does not accept a .b suffix"),
opcode->name);
- return 0;
+ break;
}
else if (! addr_op)
extended |= BYTE_OPERATION;
@@ -3488,6 +3146,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
}
input_line_pointer = line;
+ check_for_nop = nop_check_needed;
return 0;
}
@@ -4216,6 +3875,9 @@ msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
void
msp430_md_end (void)
{
+ if (check_for_nop == TRUE && warn_interrupt_nops)
+ as_warn ("assembly finished with the last instruction changing interrupt state - a NOP might be needed");
+
bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA,
target_is_430x () ? 2 : 1);
diff --git a/gas/config/tc-msp430.h b/gas/config/tc-msp430.h
index 5f14bbf..72f6dd8 100644
--- a/gas/config/tc-msp430.h
+++ b/gas/config/tc-msp430.h
@@ -124,7 +124,6 @@ extern int msp430_force_relocation_local (struct fix *);
#define tc_frob_section(sec) msp430_frob_section (sec)
extern void msp430_frob_section (asection *);
-
extern int msp430_enable_relax;
extern int msp430_enable_polys;
diff --git a/gas/doc/c-msp430.texi b/gas/doc/c-msp430.texi
index 4a46961..d8fe3ce 100644
--- a/gas/doc/c-msp430.texi
+++ b/gas/doc/c-msp430.texi
@@ -1,4 +1,4 @@
-@c Copyright 2002-2013 Free Software Foundation, Inc.
+@c Copyright 2002-2014 Free Software Foundation, Inc.
@c This is part of the GAS manual.
@c For copying conditions, see the file as.texinfo.
@ifset GENERIC
@@ -29,13 +29,12 @@
@table @code
@item -mmcu
-selects the mpu arch. If the architecture is 430Xv2 then this also
-enables NOP generation unless the @option{-mN} is also specified.
+selects the mcu architecture. If the architecture is 430Xv2 then this
+also enables NOP generation unless the @option{-mN} is also specified.
@item -mcpu
selects the cpu architecture. If the architecture is 430Xv2 then this
-also enables NOP generation unless the @option{-mN} is also
-specified.
+also enables NOP generation unless the @option{-mN} is also specified.
@item -mP
enables polymorph instructions handler.
@@ -55,17 +54,25 @@ SR}, @code{BIS #8, SR} or @code{MOV.W <>, SR}) must be
followed by a NOP instruction in order to ensure the correct
processing of interrupts. By default it is up to the programmer to
supply these NOP instructions, but this command line option enables
-the automatic insertion by the assembler. Note - the assembler does
-not peek ahead to the next instruction so it will insert a NOP even
-one is already present.
+the automatic insertion by the assembler, if they are missing.
-@c end-sanitize-msp430
-@c %redact note changed text for mN option
@item -mN
disables the generation of a NOP instruction following any instruction
that might change the interrupts enabled/disabled state. This is the
default behaviour.
+@item -mz
+tells the assembler to generate a warning message if a NOP does not
+immediately forllow an instruction that enables or disables
+interrupts. This is the default.
+
+Note that this option can be stacked with the @option{-mn} option so
+that the assembler will both warn about missing NOP instructions and
+then insert them automatically.
+
+@item -mZ
+disables warnings about missing NOP instructions.
+
@item -md
mark the object file as one that requires data to copied from ROM to
RAM at execution startup. Disabled by default.
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 86fdf4f..8c2736f 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2014-03-03 Nick Clifton <nickc@redhat.com>
+
+ * gas/msp430/bad.d: Add -mz option.
+ * gas/msp430/bad.s: Add more cases where warnings should be
+ generated.
+ * gas/msp430/bad.l: Add expected warning messages.
+
2014-02-27 Jiong Wang <jiong.wang@arm.com>
* gas/aarch64/fp-const0-parsing.s: New test.
diff --git a/gas/testsuite/gas/msp430/bad.d b/gas/testsuite/gas/msp430/bad.d
index 9302cee..1a067b5 100644
--- a/gas/testsuite/gas/msp430/bad.d
+++ b/gas/testsuite/gas/msp430/bad.d
@@ -1,3 +1,4 @@
#name: Diagnostics Quality
#source: bad.s
+#as: -mz
#error-output: bad.l
diff --git a/gas/testsuite/gas/msp430/bad.l b/gas/testsuite/gas/msp430/bad.l
index 218dcd0..8de1338 100644
--- a/gas/testsuite/gas/msp430/bad.l
+++ b/gas/testsuite/gas/msp430/bad.l
@@ -5,3 +5,10 @@
[^:]*: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
+[^:]*: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
+[^:]*: Warning: assembly finished with the last instruction changing interrupt state - a NOP might be needed
diff --git a/gas/testsuite/gas/msp430/bad.s b/gas/testsuite/gas/msp430/bad.s
index 2af83b7..b9c4af2 100644
--- a/gas/testsuite/gas/msp430/bad.s
+++ b/gas/testsuite/gas/msp430/bad.s
@@ -11,3 +11,21 @@
bis.a #8, r2
;;; FIXME: Add more tests of assembler error detection here.
+
+ ;; Changing interrupt states in two successive instructions
+ ;; might cause an interrupt to be missed. The assembler
+ ;; should warn about this, if the -mz command line option
+ ;; is used.
+ eint
+ dint
+ nop ;; No warning needed here.
+ dint
+ and #1, r11 ;; Any instruction will do, not just NOPs.
+ clr r2 ;; Aliases should trigger the warning too.
+ mov #1, r2
+ BIC #8, SR
+ BIS #8, SR
+ MOV.W #1, SR
+ ;; We will also get a warning if the last instruction in the file
+ ;; changes the interrupt state, since this file could be linked
+ ;; with another that starts with an interrupt change.