[clang] [llvm] Msp430 movx (PR #232379)

Robin Mueller via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 15 08:56:19 PDT 2026


https://github.com/robamu created https://github.com/llvm/llvm-project/pull/232379

None

>From 783d6a37fb9211b491ada0448285a4738e1ba253 Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m at pm.me>
Date: Thu, 1 Oct 2026 10:41:31 +0200
Subject: [PATCH 1/6] [MSP430][Clang] Add CPU type to generated MCU data

gen-msp430-def.py was updated to include the CPU type. Current CPU types
are msp430, msp430x and msp430xv2. This is useful information for
determining whether extended instructions are valid on a given target.

Assisted-by: Claude Code (Claude Opus 5.5)
---
 clang/include/clang/Basic/MSP430Target.def    | 1269 ++++++++---------
 .../Basic/Target/MSP430/gen-msp430-def.py     |   57 +-
 clang/lib/Driver/ToolChains/MSP430.cpp        |    4 +-
 3 files changed, 656 insertions(+), 674 deletions(-)

diff --git a/clang/include/clang/Basic/MSP430Target.def b/clang/include/clang/Basic/MSP430Target.def
index 8fd44e3ba8e719..cea5c2b038972d 100644
--- a/clang/include/clang/Basic/MSP430Target.def
+++ b/clang/include/clang/Basic/MSP430Target.def
@@ -14,649 +14,640 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef MSP430_MCU_FEAT
-#define MSP430_MCU_FEAT(NAME, HWMULT) MSP430_MCU(NAME)
-#endif
-
 #ifndef MSP430_MCU
-#define MSP430_MCU(NAME)
+#define MSP430_MCU(NAME, CPU, HWMULT)
 #endif
 
-MSP430_MCU("msp430c111")
-MSP430_MCU("msp430c1111")
-MSP430_MCU("msp430c112")
-MSP430_MCU("msp430c1121")
-MSP430_MCU("msp430c1331")
-MSP430_MCU("msp430c1351")
-MSP430_MCU("msp430c311s")
-MSP430_MCU("msp430c312")
-MSP430_MCU("msp430c313")
-MSP430_MCU("msp430c314")
-MSP430_MCU("msp430c315")
-MSP430_MCU("msp430c323")
-MSP430_MCU("msp430c325")
-MSP430_MCU("msp430c412")
-MSP430_MCU("msp430c413")
-MSP430_MCU("msp430e112")
-MSP430_MCU("msp430e313")
-MSP430_MCU("msp430e315")
-MSP430_MCU("msp430e325")
-MSP430_MCU("msp430f110")
-MSP430_MCU("msp430f1101")
-MSP430_MCU("msp430f1101a")
-MSP430_MCU("msp430f1111")
-MSP430_MCU("msp430f1111a")
-MSP430_MCU("msp430f112")
-MSP430_MCU("msp430f1121")
-MSP430_MCU("msp430f1121a")
-MSP430_MCU("msp430f1122")
-MSP430_MCU("msp430f1132")
-MSP430_MCU("msp430f122")
-MSP430_MCU("msp430f1222")
-MSP430_MCU("msp430f123")
-MSP430_MCU("msp430f1232")
-MSP430_MCU("msp430f133")
-MSP430_MCU("msp430f135")
-MSP430_MCU("msp430f155")
-MSP430_MCU("msp430f156")
-MSP430_MCU("msp430f157")
-MSP430_MCU("msp430f2001")
-MSP430_MCU("msp430f2011")
-MSP430_MCU("msp430f2002")
-MSP430_MCU("msp430f2012")
-MSP430_MCU("msp430f2003")
-MSP430_MCU("msp430f2013")
-MSP430_MCU("msp430f2101")
-MSP430_MCU("msp430f2111")
-MSP430_MCU("msp430f2121")
-MSP430_MCU("msp430f2131")
-MSP430_MCU("msp430f2112")
-MSP430_MCU("msp430f2122")
-MSP430_MCU("msp430f2132")
-MSP430_MCU("msp430f2232")
-MSP430_MCU("msp430f2252")
-MSP430_MCU("msp430f2272")
-MSP430_MCU("msp430f2234")
-MSP430_MCU("msp430f2254")
-MSP430_MCU("msp430f2274")
-MSP430_MCU("msp430f412")
-MSP430_MCU("msp430f413")
-MSP430_MCU("msp430f415")
-MSP430_MCU("msp430f417")
-MSP430_MCU("msp430f4132")
-MSP430_MCU("msp430f4152")
-MSP430_MCU("msp430f435")
-MSP430_MCU("msp430f436")
-MSP430_MCU("msp430f437")
-MSP430_MCU("msp430f4351")
-MSP430_MCU("msp430f4361")
-MSP430_MCU("msp430f4371")
-MSP430_MCU("msp430fe423")
-MSP430_MCU("msp430fe425")
-MSP430_MCU("msp430fe427")
-MSP430_MCU("msp430fe423a")
-MSP430_MCU("msp430fe425a")
-MSP430_MCU("msp430fe427a")
-MSP430_MCU("msp430fe4232")
-MSP430_MCU("msp430fe4242")
-MSP430_MCU("msp430fe4252")
-MSP430_MCU("msp430fe4272")
-MSP430_MCU("msp430f4250")
-MSP430_MCU("msp430f4260")
-MSP430_MCU("msp430f4270")
-MSP430_MCU("msp430fg4250")
-MSP430_MCU("msp430fg4260")
-MSP430_MCU("msp430fg4270")
-MSP430_MCU("msp430fw423")
-MSP430_MCU("msp430fw425")
-MSP430_MCU("msp430fw427")
-MSP430_MCU("msp430fw428")
-MSP430_MCU("msp430fw429")
-MSP430_MCU("msp430fg437")
-MSP430_MCU("msp430fg438")
-MSP430_MCU("msp430fg439")
-MSP430_MCU("msp430f438")
-MSP430_MCU("msp430f439")
-MSP430_MCU("msp430f477")
-MSP430_MCU("msp430f478")
-MSP430_MCU("msp430f479")
-MSP430_MCU("msp430fg477")
-MSP430_MCU("msp430fg478")
-MSP430_MCU("msp430fg479")
-MSP430_MCU("msp430p112")
-MSP430_MCU("msp430p313")
-MSP430_MCU("msp430p315")
-MSP430_MCU("msp430p315s")
-MSP430_MCU("msp430p325")
-MSP430_MCU("msp430l092")
-MSP430_MCU("msp430c091")
-MSP430_MCU("msp430c092")
-MSP430_MCU("msp430g2211")
-MSP430_MCU("msp430g2201")
-MSP430_MCU("msp430g2111")
-MSP430_MCU("msp430g2101")
-MSP430_MCU("msp430g2001")
-MSP430_MCU("msp430g2231")
-MSP430_MCU("msp430g2221")
-MSP430_MCU("msp430g2131")
-MSP430_MCU("msp430g2121")
-MSP430_MCU("msp430g2102")
-MSP430_MCU("msp430g2202")
-MSP430_MCU("msp430g2302")
-MSP430_MCU("msp430g2402")
-MSP430_MCU("msp430g2132")
-MSP430_MCU("msp430g2232")
-MSP430_MCU("msp430g2332")
-MSP430_MCU("msp430g2432")
-MSP430_MCU("msp430g2112")
-MSP430_MCU("msp430g2212")
-MSP430_MCU("msp430g2312")
-MSP430_MCU("msp430g2412")
-MSP430_MCU("msp430g2152")
-MSP430_MCU("msp430g2252")
-MSP430_MCU("msp430g2352")
-MSP430_MCU("msp430g2452")
-MSP430_MCU("msp430g2113")
-MSP430_MCU("msp430g2213")
-MSP430_MCU("msp430g2313")
-MSP430_MCU("msp430g2413")
-MSP430_MCU("msp430g2513")
-MSP430_MCU("msp430g2153")
-MSP430_MCU("msp430g2253")
-MSP430_MCU("msp430g2353")
-MSP430_MCU("msp430g2453")
-MSP430_MCU("msp430g2553")
-MSP430_MCU("msp430g2203")
-MSP430_MCU("msp430g2303")
-MSP430_MCU("msp430g2403")
-MSP430_MCU("msp430g2233")
-MSP430_MCU("msp430g2333")
-MSP430_MCU("msp430g2433")
-MSP430_MCU("msp430g2533")
-MSP430_MCU("msp430tch5e")
-MSP430_MCU("msp430g2444")
-MSP430_MCU("msp430g2544")
-MSP430_MCU("msp430g2744")
-MSP430_MCU("msp430g2755")
-MSP430_MCU("msp430g2855")
-MSP430_MCU("msp430g2955")
-MSP430_MCU("msp430g2230")
-MSP430_MCU("msp430g2210")
-MSP430_MCU("rf430frl152h")
-MSP430_MCU("rf430frl153h")
-MSP430_MCU("rf430frl154h")
-MSP430_MCU("rf430frl152h_rom")
-MSP430_MCU("rf430frl153h_rom")
-MSP430_MCU("rf430frl154h_rom")
-MSP430_MCU("msp430fr4131")
-MSP430_MCU("msp430fr4132")
-MSP430_MCU("msp430fr4133")
-MSP430_MCU("msp430fr2032")
-MSP430_MCU("msp430fr2033")
-MSP430_MCU("msp430fr2110")
-MSP430_MCU("msp430fr2111")
-MSP430_MCU("msp430fr2310")
-MSP430_MCU("msp430fr2311")
-MSP430_MCU("msp430fr2100")
-MSP430_MCU("msp430fr2000")
-
-// With 16-bit hardware multiplier
-MSP430_MCU_FEAT("msp430c336", "16bit")
-MSP430_MCU_FEAT("msp430c337", "16bit")
-MSP430_MCU_FEAT("msp430cg4616", "16bit")
-MSP430_MCU_FEAT("msp430cg4617", "16bit")
-MSP430_MCU_FEAT("msp430cg4618", "16bit")
-MSP430_MCU_FEAT("msp430cg4619", "16bit")
-MSP430_MCU_FEAT("msp430e337", "16bit")
-MSP430_MCU_FEAT("msp430f147", "16bit")
-MSP430_MCU_FEAT("msp430f148", "16bit")
-MSP430_MCU_FEAT("msp430f149", "16bit")
-MSP430_MCU_FEAT("msp430f1471", "16bit")
-MSP430_MCU_FEAT("msp430f1481", "16bit")
-MSP430_MCU_FEAT("msp430f1491", "16bit")
-MSP430_MCU_FEAT("msp430f167", "16bit")
-MSP430_MCU_FEAT("msp430f168", "16bit")
-MSP430_MCU_FEAT("msp430f169", "16bit")
-MSP430_MCU_FEAT("msp430f1610", "16bit")
-MSP430_MCU_FEAT("msp430f1611", "16bit")
-MSP430_MCU_FEAT("msp430f1612", "16bit")
-MSP430_MCU_FEAT("msp430f2330", "16bit")
-MSP430_MCU_FEAT("msp430f2350", "16bit")
-MSP430_MCU_FEAT("msp430f2370", "16bit")
-MSP430_MCU_FEAT("msp430f233", "16bit")
-MSP430_MCU_FEAT("msp430f235", "16bit")
-MSP430_MCU_FEAT("msp430f247", "16bit")
-MSP430_MCU_FEAT("msp430f248", "16bit")
-MSP430_MCU_FEAT("msp430f249", "16bit")
-MSP430_MCU_FEAT("msp430f2410", "16bit")
-MSP430_MCU_FEAT("msp430f2471", "16bit")
-MSP430_MCU_FEAT("msp430f2481", "16bit")
-MSP430_MCU_FEAT("msp430f2491", "16bit")
-MSP430_MCU_FEAT("msp430f2416", "16bit")
-MSP430_MCU_FEAT("msp430f2417", "16bit")
-MSP430_MCU_FEAT("msp430f2418", "16bit")
-MSP430_MCU_FEAT("msp430f2419", "16bit")
-MSP430_MCU_FEAT("msp430f2616", "16bit")
-MSP430_MCU_FEAT("msp430f2617", "16bit")
-MSP430_MCU_FEAT("msp430f2618", "16bit")
-MSP430_MCU_FEAT("msp430f2619", "16bit")
-MSP430_MCU_FEAT("msp430f423", "16bit")
-MSP430_MCU_FEAT("msp430f425", "16bit")
-MSP430_MCU_FEAT("msp430f427", "16bit")
-MSP430_MCU_FEAT("msp430f423a", "16bit")
-MSP430_MCU_FEAT("msp430f425a", "16bit")
-MSP430_MCU_FEAT("msp430f427a", "16bit")
-MSP430_MCU_FEAT("msp430f4481", "16bit")
-MSP430_MCU_FEAT("msp430f4491", "16bit")
-MSP430_MCU_FEAT("msp430f447", "16bit")
-MSP430_MCU_FEAT("msp430f448", "16bit")
-MSP430_MCU_FEAT("msp430f449", "16bit")
-MSP430_MCU_FEAT("msp430f46161", "16bit")
-MSP430_MCU_FEAT("msp430f46171", "16bit")
-MSP430_MCU_FEAT("msp430f46181", "16bit")
-MSP430_MCU_FEAT("msp430f46191", "16bit")
-MSP430_MCU_FEAT("msp430f4616", "16bit")
-MSP430_MCU_FEAT("msp430f4617", "16bit")
-MSP430_MCU_FEAT("msp430f4618", "16bit")
-MSP430_MCU_FEAT("msp430f4619", "16bit")
-MSP430_MCU_FEAT("msp430fg4616", "16bit")
-MSP430_MCU_FEAT("msp430fg4617", "16bit")
-MSP430_MCU_FEAT("msp430fg4618", "16bit")
-MSP430_MCU_FEAT("msp430fg4619", "16bit")
-MSP430_MCU_FEAT("msp430p337", "16bit")
-MSP430_MCU_FEAT("msp430afe221", "16bit")
-MSP430_MCU_FEAT("msp430afe231", "16bit")
-MSP430_MCU_FEAT("msp430afe251", "16bit")
-MSP430_MCU_FEAT("msp430afe222", "16bit")
-MSP430_MCU_FEAT("msp430afe232", "16bit")
-MSP430_MCU_FEAT("msp430afe252", "16bit")
-MSP430_MCU_FEAT("msp430afe223", "16bit")
-MSP430_MCU_FEAT("msp430afe233", "16bit")
-MSP430_MCU_FEAT("msp430afe253", "16bit")
-MSP430_MCU_FEAT("msp430i2020", "16bit")
-MSP430_MCU_FEAT("msp430i2021", "16bit")
-MSP430_MCU_FEAT("msp430i2030", "16bit")
-MSP430_MCU_FEAT("msp430i2031", "16bit")
-MSP430_MCU_FEAT("msp430i2040", "16bit")
-MSP430_MCU_FEAT("msp430i2041", "16bit")
-
-// With 32-bit hardware multiplier
-MSP430_MCU_FEAT("msp430f4783", "32bit")
-MSP430_MCU_FEAT("msp430f4793", "32bit")
-MSP430_MCU_FEAT("msp430f4784", "32bit")
-MSP430_MCU_FEAT("msp430f4794", "32bit")
-MSP430_MCU_FEAT("msp430f47126", "32bit")
-MSP430_MCU_FEAT("msp430f47127", "32bit")
-MSP430_MCU_FEAT("msp430f47163", "32bit")
-MSP430_MCU_FEAT("msp430f47173", "32bit")
-MSP430_MCU_FEAT("msp430f47183", "32bit")
-MSP430_MCU_FEAT("msp430f47193", "32bit")
-MSP430_MCU_FEAT("msp430f47166", "32bit")
-MSP430_MCU_FEAT("msp430f47176", "32bit")
-MSP430_MCU_FEAT("msp430f47186", "32bit")
-MSP430_MCU_FEAT("msp430f47196", "32bit")
-MSP430_MCU_FEAT("msp430f47167", "32bit")
-MSP430_MCU_FEAT("msp430f47177", "32bit")
-MSP430_MCU_FEAT("msp430f47187", "32bit")
-MSP430_MCU_FEAT("msp430f47197", "32bit")
-MSP430_MCU_FEAT("msp430f5418", "32bit")
-MSP430_MCU_FEAT("msp430f5419", "32bit")
-MSP430_MCU_FEAT("msp430f5435", "32bit")
-MSP430_MCU_FEAT("msp430f5436", "32bit")
-MSP430_MCU_FEAT("msp430f5437", "32bit")
-MSP430_MCU_FEAT("msp430f5438", "32bit")
-MSP430_MCU_FEAT("msp430f5418a", "32bit")
-MSP430_MCU_FEAT("msp430f5419a", "32bit")
-MSP430_MCU_FEAT("msp430f5435a", "32bit")
-MSP430_MCU_FEAT("msp430f5436a", "32bit")
-MSP430_MCU_FEAT("msp430f5437a", "32bit")
-MSP430_MCU_FEAT("msp430f5438a", "32bit")
-MSP430_MCU_FEAT("msp430f5212", "32bit")
-MSP430_MCU_FEAT("msp430f5213", "32bit")
-MSP430_MCU_FEAT("msp430f5214", "32bit")
-MSP430_MCU_FEAT("msp430f5217", "32bit")
-MSP430_MCU_FEAT("msp430f5218", "32bit")
-MSP430_MCU_FEAT("msp430f5219", "32bit")
-MSP430_MCU_FEAT("msp430f5222", "32bit")
-MSP430_MCU_FEAT("msp430f5223", "32bit")
-MSP430_MCU_FEAT("msp430f5224", "32bit")
-MSP430_MCU_FEAT("msp430f5227", "32bit")
-MSP430_MCU_FEAT("msp430f5228", "32bit")
-MSP430_MCU_FEAT("msp430f5229", "32bit")
-MSP430_MCU_FEAT("msp430f5232", "32bit")
-MSP430_MCU_FEAT("msp430f5234", "32bit")
-MSP430_MCU_FEAT("msp430f5237", "32bit")
-MSP430_MCU_FEAT("msp430f5239", "32bit")
-MSP430_MCU_FEAT("msp430f5242", "32bit")
-MSP430_MCU_FEAT("msp430f5244", "32bit")
-MSP430_MCU_FEAT("msp430f5247", "32bit")
-MSP430_MCU_FEAT("msp430f5249", "32bit")
-MSP430_MCU_FEAT("msp430f5304", "32bit")
-MSP430_MCU_FEAT("msp430f5308", "32bit")
-MSP430_MCU_FEAT("msp430f5309", "32bit")
-MSP430_MCU_FEAT("msp430f5310", "32bit")
-MSP430_MCU_FEAT("msp430f5340", "32bit")
-MSP430_MCU_FEAT("msp430f5341", "32bit")
-MSP430_MCU_FEAT("msp430f5342", "32bit")
-MSP430_MCU_FEAT("msp430f5324", "32bit")
-MSP430_MCU_FEAT("msp430f5325", "32bit")
-MSP430_MCU_FEAT("msp430f5326", "32bit")
-MSP430_MCU_FEAT("msp430f5327", "32bit")
-MSP430_MCU_FEAT("msp430f5328", "32bit")
-MSP430_MCU_FEAT("msp430f5329", "32bit")
-MSP430_MCU_FEAT("msp430f5500", "32bit")
-MSP430_MCU_FEAT("msp430f5501", "32bit")
-MSP430_MCU_FEAT("msp430f5502", "32bit")
-MSP430_MCU_FEAT("msp430f5503", "32bit")
-MSP430_MCU_FEAT("msp430f5504", "32bit")
-MSP430_MCU_FEAT("msp430f5505", "32bit")
-MSP430_MCU_FEAT("msp430f5506", "32bit")
-MSP430_MCU_FEAT("msp430f5507", "32bit")
-MSP430_MCU_FEAT("msp430f5508", "32bit")
-MSP430_MCU_FEAT("msp430f5509", "32bit")
-MSP430_MCU_FEAT("msp430f5510", "32bit")
-MSP430_MCU_FEAT("msp430f5513", "32bit")
-MSP430_MCU_FEAT("msp430f5514", "32bit")
-MSP430_MCU_FEAT("msp430f5515", "32bit")
-MSP430_MCU_FEAT("msp430f5517", "32bit")
-MSP430_MCU_FEAT("msp430f5519", "32bit")
-MSP430_MCU_FEAT("msp430f5521", "32bit")
-MSP430_MCU_FEAT("msp430f5522", "32bit")
-MSP430_MCU_FEAT("msp430f5524", "32bit")
-MSP430_MCU_FEAT("msp430f5525", "32bit")
-MSP430_MCU_FEAT("msp430f5526", "32bit")
-MSP430_MCU_FEAT("msp430f5527", "32bit")
-MSP430_MCU_FEAT("msp430f5528", "32bit")
-MSP430_MCU_FEAT("msp430f5529", "32bit")
-MSP430_MCU_FEAT("cc430f5133", "32bit")
-MSP430_MCU_FEAT("cc430f5135", "32bit")
-MSP430_MCU_FEAT("cc430f5137", "32bit")
-MSP430_MCU_FEAT("cc430f6125", "32bit")
-MSP430_MCU_FEAT("cc430f6126", "32bit")
-MSP430_MCU_FEAT("cc430f6127", "32bit")
-MSP430_MCU_FEAT("cc430f6135", "32bit")
-MSP430_MCU_FEAT("cc430f6137", "32bit")
-MSP430_MCU_FEAT("cc430f5123", "32bit")
-MSP430_MCU_FEAT("cc430f5125", "32bit")
-MSP430_MCU_FEAT("cc430f5143", "32bit")
-MSP430_MCU_FEAT("cc430f5145", "32bit")
-MSP430_MCU_FEAT("cc430f5147", "32bit")
-MSP430_MCU_FEAT("cc430f6143", "32bit")
-MSP430_MCU_FEAT("cc430f6145", "32bit")
-MSP430_MCU_FEAT("cc430f6147", "32bit")
-MSP430_MCU_FEAT("msp430f5333", "32bit")
-MSP430_MCU_FEAT("msp430f5335", "32bit")
-MSP430_MCU_FEAT("msp430f5336", "32bit")
-MSP430_MCU_FEAT("msp430f5338", "32bit")
-MSP430_MCU_FEAT("msp430f5630", "32bit")
-MSP430_MCU_FEAT("msp430f5631", "32bit")
-MSP430_MCU_FEAT("msp430f5632", "32bit")
-MSP430_MCU_FEAT("msp430f5633", "32bit")
-MSP430_MCU_FEAT("msp430f5634", "32bit")
-MSP430_MCU_FEAT("msp430f5635", "32bit")
-MSP430_MCU_FEAT("msp430f5636", "32bit")
-MSP430_MCU_FEAT("msp430f5637", "32bit")
-MSP430_MCU_FEAT("msp430f5638", "32bit")
-MSP430_MCU_FEAT("msp430f6433", "32bit")
-MSP430_MCU_FEAT("msp430f6435", "32bit")
-MSP430_MCU_FEAT("msp430f6436", "32bit")
-MSP430_MCU_FEAT("msp430f6438", "32bit")
-MSP430_MCU_FEAT("msp430f6630", "32bit")
-MSP430_MCU_FEAT("msp430f6631", "32bit")
-MSP430_MCU_FEAT("msp430f6632", "32bit")
-MSP430_MCU_FEAT("msp430f6633", "32bit")
-MSP430_MCU_FEAT("msp430f6634", "32bit")
-MSP430_MCU_FEAT("msp430f6635", "32bit")
-MSP430_MCU_FEAT("msp430f6636", "32bit")
-MSP430_MCU_FEAT("msp430f6637", "32bit")
-MSP430_MCU_FEAT("msp430f6638", "32bit")
-MSP430_MCU_FEAT("msp430f5358", "32bit")
-MSP430_MCU_FEAT("msp430f5359", "32bit")
-MSP430_MCU_FEAT("msp430f5658", "32bit")
-MSP430_MCU_FEAT("msp430f5659", "32bit")
-MSP430_MCU_FEAT("msp430f6458", "32bit")
-MSP430_MCU_FEAT("msp430f6459", "32bit")
-MSP430_MCU_FEAT("msp430f6658", "32bit")
-MSP430_MCU_FEAT("msp430f6659", "32bit")
-MSP430_MCU_FEAT("msp430fg6425", "32bit")
-MSP430_MCU_FEAT("msp430fg6426", "32bit")
-MSP430_MCU_FEAT("msp430fg6625", "32bit")
-MSP430_MCU_FEAT("msp430fg6626", "32bit")
-MSP430_MCU_FEAT("msp430f5131", "32bit")
-MSP430_MCU_FEAT("msp430f5151", "32bit")
-MSP430_MCU_FEAT("msp430f5171", "32bit")
-MSP430_MCU_FEAT("msp430f5132", "32bit")
-MSP430_MCU_FEAT("msp430f5152", "32bit")
-MSP430_MCU_FEAT("msp430f5172", "32bit")
-MSP430_MCU_FEAT("msp430f6720", "32bit")
-MSP430_MCU_FEAT("msp430f6721", "32bit")
-MSP430_MCU_FEAT("msp430f6723", "32bit")
-MSP430_MCU_FEAT("msp430f6724", "32bit")
-MSP430_MCU_FEAT("msp430f6725", "32bit")
-MSP430_MCU_FEAT("msp430f6726", "32bit")
-MSP430_MCU_FEAT("msp430f6730", "32bit")
-MSP430_MCU_FEAT("msp430f6731", "32bit")
-MSP430_MCU_FEAT("msp430f6733", "32bit")
-MSP430_MCU_FEAT("msp430f6734", "32bit")
-MSP430_MCU_FEAT("msp430f6735", "32bit")
-MSP430_MCU_FEAT("msp430f6736", "32bit")
-MSP430_MCU_FEAT("msp430f67621", "32bit")
-MSP430_MCU_FEAT("msp430f67641", "32bit")
-MSP430_MCU_FEAT("msp430f6720a", "32bit")
-MSP430_MCU_FEAT("msp430f6721a", "32bit")
-MSP430_MCU_FEAT("msp430f6723a", "32bit")
-MSP430_MCU_FEAT("msp430f6724a", "32bit")
-MSP430_MCU_FEAT("msp430f6725a", "32bit")
-MSP430_MCU_FEAT("msp430f6726a", "32bit")
-MSP430_MCU_FEAT("msp430f6730a", "32bit")
-MSP430_MCU_FEAT("msp430f6731a", "32bit")
-MSP430_MCU_FEAT("msp430f6733a", "32bit")
-MSP430_MCU_FEAT("msp430f6734a", "32bit")
-MSP430_MCU_FEAT("msp430f6735a", "32bit")
-MSP430_MCU_FEAT("msp430f6736a", "32bit")
-MSP430_MCU_FEAT("msp430f67621a", "32bit")
-MSP430_MCU_FEAT("msp430f67641a", "32bit")
-MSP430_MCU_FEAT("msp430f67451", "32bit")
-MSP430_MCU_FEAT("msp430f67651", "32bit")
-MSP430_MCU_FEAT("msp430f67751", "32bit")
-MSP430_MCU_FEAT("msp430f67461", "32bit")
-MSP430_MCU_FEAT("msp430f67661", "32bit")
-MSP430_MCU_FEAT("msp430f67761", "32bit")
-MSP430_MCU_FEAT("msp430f67471", "32bit")
-MSP430_MCU_FEAT("msp430f67671", "32bit")
-MSP430_MCU_FEAT("msp430f67771", "32bit")
-MSP430_MCU_FEAT("msp430f67481", "32bit")
-MSP430_MCU_FEAT("msp430f67681", "32bit")
-MSP430_MCU_FEAT("msp430f67781", "32bit")
-MSP430_MCU_FEAT("msp430f67491", "32bit")
-MSP430_MCU_FEAT("msp430f67691", "32bit")
-MSP430_MCU_FEAT("msp430f67791", "32bit")
-MSP430_MCU_FEAT("msp430f6745", "32bit")
-MSP430_MCU_FEAT("msp430f6765", "32bit")
-MSP430_MCU_FEAT("msp430f6775", "32bit")
-MSP430_MCU_FEAT("msp430f6746", "32bit")
-MSP430_MCU_FEAT("msp430f6766", "32bit")
-MSP430_MCU_FEAT("msp430f6776", "32bit")
-MSP430_MCU_FEAT("msp430f6747", "32bit")
-MSP430_MCU_FEAT("msp430f6767", "32bit")
-MSP430_MCU_FEAT("msp430f6777", "32bit")
-MSP430_MCU_FEAT("msp430f6748", "32bit")
-MSP430_MCU_FEAT("msp430f6768", "32bit")
-MSP430_MCU_FEAT("msp430f6778", "32bit")
-MSP430_MCU_FEAT("msp430f6749", "32bit")
-MSP430_MCU_FEAT("msp430f6769", "32bit")
-MSP430_MCU_FEAT("msp430f6779", "32bit")
-MSP430_MCU_FEAT("msp430f67451a", "32bit")
-MSP430_MCU_FEAT("msp430f67651a", "32bit")
-MSP430_MCU_FEAT("msp430f67751a", "32bit")
-MSP430_MCU_FEAT("msp430f67461a", "32bit")
-MSP430_MCU_FEAT("msp430f67661a", "32bit")
-MSP430_MCU_FEAT("msp430f67761a", "32bit")
-MSP430_MCU_FEAT("msp430f67471a", "32bit")
-MSP430_MCU_FEAT("msp430f67671a", "32bit")
-MSP430_MCU_FEAT("msp430f67771a", "32bit")
-MSP430_MCU_FEAT("msp430f67481a", "32bit")
-MSP430_MCU_FEAT("msp430f67681a", "32bit")
-MSP430_MCU_FEAT("msp430f67781a", "32bit")
-MSP430_MCU_FEAT("msp430f67491a", "32bit")
-MSP430_MCU_FEAT("msp430f67691a", "32bit")
-MSP430_MCU_FEAT("msp430f67791a", "32bit")
-MSP430_MCU_FEAT("msp430f6745a", "32bit")
-MSP430_MCU_FEAT("msp430f6765a", "32bit")
-MSP430_MCU_FEAT("msp430f6775a", "32bit")
-MSP430_MCU_FEAT("msp430f6746a", "32bit")
-MSP430_MCU_FEAT("msp430f6766a", "32bit")
-MSP430_MCU_FEAT("msp430f6776a", "32bit")
-MSP430_MCU_FEAT("msp430f6747a", "32bit")
-MSP430_MCU_FEAT("msp430f6767a", "32bit")
-MSP430_MCU_FEAT("msp430f6777a", "32bit")
-MSP430_MCU_FEAT("msp430f6748a", "32bit")
-MSP430_MCU_FEAT("msp430f6768a", "32bit")
-MSP430_MCU_FEAT("msp430f6778a", "32bit")
-MSP430_MCU_FEAT("msp430f6749a", "32bit")
-MSP430_MCU_FEAT("msp430f6769a", "32bit")
-MSP430_MCU_FEAT("msp430f6779a", "32bit")
-MSP430_MCU_FEAT("msp430fr5720", "32bit")
-MSP430_MCU_FEAT("msp430fr5721", "32bit")
-MSP430_MCU_FEAT("msp430fr5722", "32bit")
-MSP430_MCU_FEAT("msp430fr5723", "32bit")
-MSP430_MCU_FEAT("msp430fr5724", "32bit")
-MSP430_MCU_FEAT("msp430fr5725", "32bit")
-MSP430_MCU_FEAT("msp430fr5726", "32bit")
-MSP430_MCU_FEAT("msp430fr5727", "32bit")
-MSP430_MCU_FEAT("msp430fr5728", "32bit")
-MSP430_MCU_FEAT("msp430fr5729", "32bit")
-MSP430_MCU_FEAT("msp430fr5730", "32bit")
-MSP430_MCU_FEAT("msp430fr5731", "32bit")
-MSP430_MCU_FEAT("msp430fr5732", "32bit")
-MSP430_MCU_FEAT("msp430fr5733", "32bit")
-MSP430_MCU_FEAT("msp430fr5734", "32bit")
-MSP430_MCU_FEAT("msp430fr5735", "32bit")
-MSP430_MCU_FEAT("msp430fr5736", "32bit")
-MSP430_MCU_FEAT("msp430fr5737", "32bit")
-MSP430_MCU_FEAT("msp430fr5738", "32bit")
-MSP430_MCU_FEAT("msp430fr5739", "32bit")
-MSP430_MCU_FEAT("msp430bt5190", "32bit")
-MSP430_MCU_FEAT("msp430fr5857", "32bit")
-MSP430_MCU_FEAT("msp430fr5858", "32bit")
-MSP430_MCU_FEAT("msp430fr5859", "32bit")
-MSP430_MCU_FEAT("msp430fr5847", "32bit")
-MSP430_MCU_FEAT("msp430fr58471", "32bit")
-MSP430_MCU_FEAT("msp430fr5848", "32bit")
-MSP430_MCU_FEAT("msp430fr5849", "32bit")
-MSP430_MCU_FEAT("msp430fr5867", "32bit")
-MSP430_MCU_FEAT("msp430fr58671", "32bit")
-MSP430_MCU_FEAT("msp430fr5868", "32bit")
-MSP430_MCU_FEAT("msp430fr5869", "32bit")
-MSP430_MCU_FEAT("msp430fr5957", "32bit")
-MSP430_MCU_FEAT("msp430fr5958", "32bit")
-MSP430_MCU_FEAT("msp430fr5959", "32bit")
-MSP430_MCU_FEAT("msp430fr5947", "32bit")
-MSP430_MCU_FEAT("msp430fr59471", "32bit")
-MSP430_MCU_FEAT("msp430fr5948", "32bit")
-MSP430_MCU_FEAT("msp430fr5949", "32bit")
-MSP430_MCU_FEAT("msp430fr5967", "32bit")
-MSP430_MCU_FEAT("msp430fr5968", "32bit")
-MSP430_MCU_FEAT("msp430fr5969", "32bit")
-MSP430_MCU_FEAT("msp430fr59691", "32bit")
-MSP430_MCU_FEAT("rf430f5175", "32bit")
-MSP430_MCU_FEAT("rf430f5155", "32bit")
-MSP430_MCU_FEAT("rf430f5144", "32bit")
-MSP430_MCU_FEAT("msp430fr69271", "32bit")
-MSP430_MCU_FEAT("msp430fr68791", "32bit")
-MSP430_MCU_FEAT("msp430fr69791", "32bit")
-MSP430_MCU_FEAT("msp430fr6927", "32bit")
-MSP430_MCU_FEAT("msp430fr6928", "32bit")
-MSP430_MCU_FEAT("msp430fr6877", "32bit")
-MSP430_MCU_FEAT("msp430fr6977", "32bit")
-MSP430_MCU_FEAT("msp430fr6879", "32bit")
-MSP430_MCU_FEAT("msp430fr6979", "32bit")
-MSP430_MCU_FEAT("msp430fr58891", "32bit")
-MSP430_MCU_FEAT("msp430fr68891", "32bit")
-MSP430_MCU_FEAT("msp430fr59891", "32bit")
-MSP430_MCU_FEAT("msp430fr69891", "32bit")
-MSP430_MCU_FEAT("msp430fr5887", "32bit")
-MSP430_MCU_FEAT("msp430fr5888", "32bit")
-MSP430_MCU_FEAT("msp430fr5889", "32bit")
-MSP430_MCU_FEAT("msp430fr6887", "32bit")
-MSP430_MCU_FEAT("msp430fr6888", "32bit")
-MSP430_MCU_FEAT("msp430fr6889", "32bit")
-MSP430_MCU_FEAT("msp430fr5986", "32bit")
-MSP430_MCU_FEAT("msp430fr5987", "32bit")
-MSP430_MCU_FEAT("msp430fr5988", "32bit")
-MSP430_MCU_FEAT("msp430fr5989", "32bit")
-MSP430_MCU_FEAT("msp430fr6987", "32bit")
-MSP430_MCU_FEAT("msp430fr6988", "32bit")
-MSP430_MCU_FEAT("msp430fr6989", "32bit")
-MSP430_MCU_FEAT("msp430fr5922", "32bit")
-MSP430_MCU_FEAT("msp430fr5870", "32bit")
-MSP430_MCU_FEAT("msp430fr5970", "32bit")
-MSP430_MCU_FEAT("msp430fr5872", "32bit")
-MSP430_MCU_FEAT("msp430fr5972", "32bit")
-MSP430_MCU_FEAT("msp430fr6820", "32bit")
-MSP430_MCU_FEAT("msp430fr6920", "32bit")
-MSP430_MCU_FEAT("msp430fr6822", "32bit")
-MSP430_MCU_FEAT("msp430fr6922", "32bit")
-MSP430_MCU_FEAT("msp430fr6870", "32bit")
-MSP430_MCU_FEAT("msp430fr6970", "32bit")
-MSP430_MCU_FEAT("msp430fr6872", "32bit")
-MSP430_MCU_FEAT("msp430fr6972", "32bit")
-MSP430_MCU_FEAT("msp430fr59221", "32bit")
-MSP430_MCU_FEAT("msp430fr58721", "32bit")
-MSP430_MCU_FEAT("msp430fr59721", "32bit")
-MSP430_MCU_FEAT("msp430fr68221", "32bit")
-MSP430_MCU_FEAT("msp430fr69221", "32bit")
-MSP430_MCU_FEAT("msp430fr68721", "32bit")
-MSP430_MCU_FEAT("msp430fr69721", "32bit")
-MSP430_MCU_FEAT("msp430sl5438a", "32bit")
-MSP430_MCU_FEAT("msp430fr2433", "32bit")
-MSP430_MCU_FEAT("msp430fr2532", "32bit")
-MSP430_MCU_FEAT("msp430fr2533", "32bit")
-MSP430_MCU_FEAT("msp430fr2632", "32bit")
-MSP430_MCU_FEAT("msp430fr2633", "32bit")
-MSP430_MCU_FEAT("msp430f5252", "32bit")
-MSP430_MCU_FEAT("msp430f5253", "32bit")
-MSP430_MCU_FEAT("msp430f5254", "32bit")
-MSP430_MCU_FEAT("msp430f5255", "32bit")
-MSP430_MCU_FEAT("msp430f5256", "32bit")
-MSP430_MCU_FEAT("msp430f5257", "32bit")
-MSP430_MCU_FEAT("msp430f5258", "32bit")
-MSP430_MCU_FEAT("msp430f5259", "32bit")
-MSP430_MCU_FEAT("msp430fr5962", "32bit")
-MSP430_MCU_FEAT("msp430fr5964", "32bit")
-MSP430_MCU_FEAT("msp430fr5992", "32bit")
-MSP430_MCU_FEAT("msp430fr5994", "32bit")
-MSP430_MCU_FEAT("msp430fr59941", "32bit")
-MSP430_MCU_FEAT("msp430fr2355", "32bit")
-MSP430_MCU_FEAT("msp430fr2155", "32bit")
-MSP430_MCU_FEAT("msp430fr2353", "32bit")
-MSP430_MCU_FEAT("msp430fr2153", "32bit")
-MSP430_MCU_FEAT("msp430fr2522", "32bit")
-MSP430_MCU_FEAT("msp430fr2512", "32bit")
-MSP430_MCU_FEAT("msp430fr2422", "32bit")
-MSP430_MCU_FEAT("msp430fr2676", "32bit")
-MSP430_MCU_FEAT("msp430fr2476", "32bit")
-MSP430_MCU_FEAT("msp430fr2675", "32bit")
-MSP430_MCU_FEAT("msp430fr2673", "32bit")
-MSP430_MCU_FEAT("msp430fr2475", "32bit")
-MSP430_MCU_FEAT("msp430fr2672", "32bit")
-MSP430_MCU_FEAT("msp430fr6043", "32bit")
-MSP430_MCU_FEAT("msp430fr5043", "32bit")
-MSP430_MCU_FEAT("msp430fr6041", "32bit")
-MSP430_MCU_FEAT("msp430fr60431", "32bit")
-MSP430_MCU_FEAT("msp430fr5041", "32bit")
-MSP430_MCU_FEAT("msp430fr50431", "32bit")
-MSP430_MCU_FEAT("msp430fr6005", "32bit")
-MSP430_MCU_FEAT("msp430fr6047", "32bit")
-MSP430_MCU_FEAT("msp430fr6037", "32bit")
-MSP430_MCU_FEAT("msp430fr6045", "32bit")
-MSP430_MCU_FEAT("msp430fr60471", "32bit")
-MSP430_MCU_FEAT("msp430fr6035", "32bit")
-MSP430_MCU_FEAT("msp430fr6007", "32bit")
-MSP430_MCU_FEAT("msp430fr60371", "32bit")
+MSP430_MCU("msp430c111", "msp430", "none")
+MSP430_MCU("msp430c1111", "msp430", "none")
+MSP430_MCU("msp430c112", "msp430", "none")
+MSP430_MCU("msp430c1121", "msp430", "none")
+MSP430_MCU("msp430c1331", "msp430", "none")
+MSP430_MCU("msp430c1351", "msp430", "none")
+MSP430_MCU("msp430c311s", "msp430", "none")
+MSP430_MCU("msp430c312", "msp430", "none")
+MSP430_MCU("msp430c313", "msp430", "none")
+MSP430_MCU("msp430c314", "msp430", "none")
+MSP430_MCU("msp430c315", "msp430", "none")
+MSP430_MCU("msp430c323", "msp430", "none")
+MSP430_MCU("msp430c325", "msp430", "none")
+MSP430_MCU("msp430c336", "msp430", "16bit")
+MSP430_MCU("msp430c337", "msp430", "16bit")
+MSP430_MCU("msp430c412", "msp430", "none")
+MSP430_MCU("msp430c413", "msp430", "none")
+MSP430_MCU("msp430cg4616", "msp430x", "16bit")
+MSP430_MCU("msp430cg4617", "msp430x", "16bit")
+MSP430_MCU("msp430cg4618", "msp430x", "16bit")
+MSP430_MCU("msp430cg4619", "msp430x", "16bit")
+MSP430_MCU("msp430e112", "msp430", "none")
+MSP430_MCU("msp430e313", "msp430", "none")
+MSP430_MCU("msp430e315", "msp430", "none")
+MSP430_MCU("msp430e325", "msp430", "none")
+MSP430_MCU("msp430e337", "msp430", "16bit")
+MSP430_MCU("msp430f110", "msp430", "none")
+MSP430_MCU("msp430f1101", "msp430", "none")
+MSP430_MCU("msp430f1101a", "msp430", "none")
+MSP430_MCU("msp430f1111", "msp430", "none")
+MSP430_MCU("msp430f1111a", "msp430", "none")
+MSP430_MCU("msp430f112", "msp430", "none")
+MSP430_MCU("msp430f1121", "msp430", "none")
+MSP430_MCU("msp430f1121a", "msp430", "none")
+MSP430_MCU("msp430f1122", "msp430", "none")
+MSP430_MCU("msp430f1132", "msp430", "none")
+MSP430_MCU("msp430f122", "msp430", "none")
+MSP430_MCU("msp430f1222", "msp430", "none")
+MSP430_MCU("msp430f123", "msp430", "none")
+MSP430_MCU("msp430f1232", "msp430", "none")
+MSP430_MCU("msp430f133", "msp430", "none")
+MSP430_MCU("msp430f135", "msp430", "none")
+MSP430_MCU("msp430f147", "msp430", "16bit")
+MSP430_MCU("msp430f148", "msp430", "16bit")
+MSP430_MCU("msp430f149", "msp430", "16bit")
+MSP430_MCU("msp430f1471", "msp430", "16bit")
+MSP430_MCU("msp430f1481", "msp430", "16bit")
+MSP430_MCU("msp430f1491", "msp430", "16bit")
+MSP430_MCU("msp430f155", "msp430", "none")
+MSP430_MCU("msp430f156", "msp430", "none")
+MSP430_MCU("msp430f157", "msp430", "none")
+MSP430_MCU("msp430f167", "msp430", "16bit")
+MSP430_MCU("msp430f168", "msp430", "16bit")
+MSP430_MCU("msp430f169", "msp430", "16bit")
+MSP430_MCU("msp430f1610", "msp430", "16bit")
+MSP430_MCU("msp430f1611", "msp430", "16bit")
+MSP430_MCU("msp430f1612", "msp430", "16bit")
+MSP430_MCU("msp430f2001", "msp430", "none")
+MSP430_MCU("msp430f2011", "msp430", "none")
+MSP430_MCU("msp430f2002", "msp430", "none")
+MSP430_MCU("msp430f2012", "msp430", "none")
+MSP430_MCU("msp430f2003", "msp430", "none")
+MSP430_MCU("msp430f2013", "msp430", "none")
+MSP430_MCU("msp430f2101", "msp430", "none")
+MSP430_MCU("msp430f2111", "msp430", "none")
+MSP430_MCU("msp430f2121", "msp430", "none")
+MSP430_MCU("msp430f2131", "msp430", "none")
+MSP430_MCU("msp430f2112", "msp430", "none")
+MSP430_MCU("msp430f2122", "msp430", "none")
+MSP430_MCU("msp430f2132", "msp430", "none")
+MSP430_MCU("msp430f2232", "msp430", "none")
+MSP430_MCU("msp430f2252", "msp430", "none")
+MSP430_MCU("msp430f2272", "msp430", "none")
+MSP430_MCU("msp430f2234", "msp430", "none")
+MSP430_MCU("msp430f2254", "msp430", "none")
+MSP430_MCU("msp430f2274", "msp430", "none")
+MSP430_MCU("msp430f2330", "msp430", "16bit")
+MSP430_MCU("msp430f2350", "msp430", "16bit")
+MSP430_MCU("msp430f2370", "msp430", "16bit")
+MSP430_MCU("msp430f233", "msp430", "16bit")
+MSP430_MCU("msp430f235", "msp430", "16bit")
+MSP430_MCU("msp430f247", "msp430", "16bit")
+MSP430_MCU("msp430f248", "msp430", "16bit")
+MSP430_MCU("msp430f249", "msp430", "16bit")
+MSP430_MCU("msp430f2410", "msp430", "16bit")
+MSP430_MCU("msp430f2471", "msp430", "16bit")
+MSP430_MCU("msp430f2481", "msp430", "16bit")
+MSP430_MCU("msp430f2491", "msp430", "16bit")
+MSP430_MCU("msp430f2416", "msp430x", "16bit")
+MSP430_MCU("msp430f2417", "msp430x", "16bit")
+MSP430_MCU("msp430f2418", "msp430x", "16bit")
+MSP430_MCU("msp430f2419", "msp430x", "16bit")
+MSP430_MCU("msp430f2616", "msp430x", "16bit")
+MSP430_MCU("msp430f2617", "msp430x", "16bit")
+MSP430_MCU("msp430f2618", "msp430x", "16bit")
+MSP430_MCU("msp430f2619", "msp430x", "16bit")
+MSP430_MCU("msp430f412", "msp430", "none")
+MSP430_MCU("msp430f413", "msp430", "none")
+MSP430_MCU("msp430f415", "msp430", "none")
+MSP430_MCU("msp430f417", "msp430", "none")
+MSP430_MCU("msp430f4132", "msp430", "none")
+MSP430_MCU("msp430f4152", "msp430", "none")
+MSP430_MCU("msp430f423", "msp430", "16bit")
+MSP430_MCU("msp430f425", "msp430", "16bit")
+MSP430_MCU("msp430f427", "msp430", "16bit")
+MSP430_MCU("msp430f423a", "msp430", "16bit")
+MSP430_MCU("msp430f425a", "msp430", "16bit")
+MSP430_MCU("msp430f427a", "msp430", "16bit")
+MSP430_MCU("msp430f435", "msp430", "none")
+MSP430_MCU("msp430f436", "msp430", "none")
+MSP430_MCU("msp430f437", "msp430", "none")
+MSP430_MCU("msp430f4351", "msp430", "none")
+MSP430_MCU("msp430f4361", "msp430", "none")
+MSP430_MCU("msp430f4371", "msp430", "none")
+MSP430_MCU("msp430f4481", "msp430", "16bit")
+MSP430_MCU("msp430f4491", "msp430", "16bit")
+MSP430_MCU("msp430f447", "msp430", "16bit")
+MSP430_MCU("msp430f448", "msp430", "16bit")
+MSP430_MCU("msp430f449", "msp430", "16bit")
+MSP430_MCU("msp430fe423", "msp430", "none")
+MSP430_MCU("msp430fe425", "msp430", "none")
+MSP430_MCU("msp430fe427", "msp430", "none")
+MSP430_MCU("msp430fe423a", "msp430", "none")
+MSP430_MCU("msp430fe425a", "msp430", "none")
+MSP430_MCU("msp430fe427a", "msp430", "none")
+MSP430_MCU("msp430fe4232", "msp430", "none")
+MSP430_MCU("msp430fe4242", "msp430", "none")
+MSP430_MCU("msp430fe4252", "msp430", "none")
+MSP430_MCU("msp430fe4272", "msp430", "none")
+MSP430_MCU("msp430f4783", "msp430", "32bit")
+MSP430_MCU("msp430f4793", "msp430", "32bit")
+MSP430_MCU("msp430f4784", "msp430", "32bit")
+MSP430_MCU("msp430f4794", "msp430", "32bit")
+MSP430_MCU("msp430f47126", "msp430x", "32bit")
+MSP430_MCU("msp430f47127", "msp430x", "32bit")
+MSP430_MCU("msp430f47163", "msp430x", "32bit")
+MSP430_MCU("msp430f47173", "msp430x", "32bit")
+MSP430_MCU("msp430f47183", "msp430x", "32bit")
+MSP430_MCU("msp430f47193", "msp430x", "32bit")
+MSP430_MCU("msp430f47166", "msp430x", "32bit")
+MSP430_MCU("msp430f47176", "msp430x", "32bit")
+MSP430_MCU("msp430f47186", "msp430x", "32bit")
+MSP430_MCU("msp430f47196", "msp430x", "32bit")
+MSP430_MCU("msp430f47167", "msp430x", "32bit")
+MSP430_MCU("msp430f47177", "msp430x", "32bit")
+MSP430_MCU("msp430f47187", "msp430x", "32bit")
+MSP430_MCU("msp430f47197", "msp430x", "32bit")
+MSP430_MCU("msp430f4250", "msp430", "none")
+MSP430_MCU("msp430f4260", "msp430", "none")
+MSP430_MCU("msp430f4270", "msp430", "none")
+MSP430_MCU("msp430fg4250", "msp430", "none")
+MSP430_MCU("msp430fg4260", "msp430", "none")
+MSP430_MCU("msp430fg4270", "msp430", "none")
+MSP430_MCU("msp430fw423", "msp430", "none")
+MSP430_MCU("msp430fw425", "msp430", "none")
+MSP430_MCU("msp430fw427", "msp430", "none")
+MSP430_MCU("msp430fw428", "msp430", "none")
+MSP430_MCU("msp430fw429", "msp430", "none")
+MSP430_MCU("msp430fg437", "msp430", "none")
+MSP430_MCU("msp430fg438", "msp430", "none")
+MSP430_MCU("msp430fg439", "msp430", "none")
+MSP430_MCU("msp430f438", "msp430", "none")
+MSP430_MCU("msp430f439", "msp430", "none")
+MSP430_MCU("msp430f477", "msp430", "none")
+MSP430_MCU("msp430f478", "msp430", "none")
+MSP430_MCU("msp430f479", "msp430", "none")
+MSP430_MCU("msp430fg477", "msp430", "none")
+MSP430_MCU("msp430fg478", "msp430", "none")
+MSP430_MCU("msp430fg479", "msp430", "none")
+MSP430_MCU("msp430f46161", "msp430x", "16bit")
+MSP430_MCU("msp430f46171", "msp430x", "16bit")
+MSP430_MCU("msp430f46181", "msp430x", "16bit")
+MSP430_MCU("msp430f46191", "msp430x", "16bit")
+MSP430_MCU("msp430f4616", "msp430x", "16bit")
+MSP430_MCU("msp430f4617", "msp430x", "16bit")
+MSP430_MCU("msp430f4618", "msp430x", "16bit")
+MSP430_MCU("msp430f4619", "msp430x", "16bit")
+MSP430_MCU("msp430fg4616", "msp430x", "16bit")
+MSP430_MCU("msp430fg4617", "msp430x", "16bit")
+MSP430_MCU("msp430fg4618", "msp430x", "16bit")
+MSP430_MCU("msp430fg4619", "msp430x", "16bit")
+MSP430_MCU("msp430f5418", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5419", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5435", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5436", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5437", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5438", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5418a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5419a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5435a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5436a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5437a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5438a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5212", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5213", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5214", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5217", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5218", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5219", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5222", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5223", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5224", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5227", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5228", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5229", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5232", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5234", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5237", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5239", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5242", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5244", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5247", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5249", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5304", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5308", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5309", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5310", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5340", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5341", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5342", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5324", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5325", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5326", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5327", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5328", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5329", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5500", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5501", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5502", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5503", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5504", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5505", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5506", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5507", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5508", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5509", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5510", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5513", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5514", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5515", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5517", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5519", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5521", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5522", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5524", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5525", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5526", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5527", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5528", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5529", "msp430xv2", "32bit")
+MSP430_MCU("msp430p112", "msp430", "none")
+MSP430_MCU("msp430p313", "msp430", "none")
+MSP430_MCU("msp430p315", "msp430", "none")
+MSP430_MCU("msp430p315s", "msp430", "none")
+MSP430_MCU("msp430p325", "msp430", "none")
+MSP430_MCU("msp430p337", "msp430", "16bit")
+MSP430_MCU("cc430f5133", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5135", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5137", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6125", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6126", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6127", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6135", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6137", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5123", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5125", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5143", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5145", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5147", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6143", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6145", "msp430xv2", "32bit")
+MSP430_MCU("cc430f6147", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5333", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5335", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5336", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5338", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5630", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5631", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5632", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5633", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5634", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5635", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5636", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5637", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5638", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6433", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6435", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6436", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6438", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6630", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6631", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6632", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6633", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6634", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6635", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6636", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6637", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6638", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5358", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5359", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5658", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5659", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6458", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6459", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6658", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6659", "msp430xv2", "32bit")
+MSP430_MCU("msp430fg6425", "msp430xv2", "32bit")
+MSP430_MCU("msp430fg6426", "msp430xv2", "32bit")
+MSP430_MCU("msp430fg6625", "msp430xv2", "32bit")
+MSP430_MCU("msp430fg6626", "msp430xv2", "32bit")
+MSP430_MCU("msp430l092", "msp430", "none")
+MSP430_MCU("msp430c091", "msp430", "none")
+MSP430_MCU("msp430c092", "msp430", "none")
+MSP430_MCU("msp430f5131", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5151", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5171", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5132", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5152", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5172", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6720", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6721", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6723", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6724", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6725", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6726", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6730", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6731", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6733", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6734", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6735", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6736", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67621", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67641", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6720a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6721a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6723a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6724a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6725a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6726a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6730a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6731a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6733a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6734a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6735a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6736a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67621a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67641a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67451", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67651", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67751", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67461", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67661", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67761", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67471", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67671", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67771", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67481", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67681", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67781", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67491", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67691", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67791", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6745", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6765", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6775", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6746", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6766", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6776", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6747", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6767", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6777", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6748", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6768", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6778", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6749", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6769", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6779", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67451a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67651a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67751a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67461a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67661a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67761a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67471a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67671a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67771a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67481a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67681a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67781a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67491a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67691a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f67791a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6745a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6765a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6775a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6746a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6766a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6776a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6747a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6767a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6777a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6748a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6768a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6778a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6749a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6769a", "msp430xv2", "32bit")
+MSP430_MCU("msp430f6779a", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5720", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5721", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5722", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5723", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5724", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5725", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5726", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5727", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5728", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5729", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5730", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5731", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5732", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5733", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5734", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5735", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5736", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5737", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5738", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5739", "msp430xv2", "32bit")
+MSP430_MCU("msp430g2211", "msp430", "none")
+MSP430_MCU("msp430g2201", "msp430", "none")
+MSP430_MCU("msp430g2111", "msp430", "none")
+MSP430_MCU("msp430g2101", "msp430", "none")
+MSP430_MCU("msp430g2001", "msp430", "none")
+MSP430_MCU("msp430g2231", "msp430", "none")
+MSP430_MCU("msp430g2221", "msp430", "none")
+MSP430_MCU("msp430g2131", "msp430", "none")
+MSP430_MCU("msp430g2121", "msp430", "none")
+MSP430_MCU("msp430afe221", "msp430", "16bit")
+MSP430_MCU("msp430afe231", "msp430", "16bit")
+MSP430_MCU("msp430afe251", "msp430", "16bit")
+MSP430_MCU("msp430afe222", "msp430", "16bit")
+MSP430_MCU("msp430afe232", "msp430", "16bit")
+MSP430_MCU("msp430afe252", "msp430", "16bit")
+MSP430_MCU("msp430afe223", "msp430", "16bit")
+MSP430_MCU("msp430afe233", "msp430", "16bit")
+MSP430_MCU("msp430afe253", "msp430", "16bit")
+MSP430_MCU("msp430g2102", "msp430", "none")
+MSP430_MCU("msp430g2202", "msp430", "none")
+MSP430_MCU("msp430g2302", "msp430", "none")
+MSP430_MCU("msp430g2402", "msp430", "none")
+MSP430_MCU("msp430g2132", "msp430", "none")
+MSP430_MCU("msp430g2232", "msp430", "none")
+MSP430_MCU("msp430g2332", "msp430", "none")
+MSP430_MCU("msp430g2432", "msp430", "none")
+MSP430_MCU("msp430g2112", "msp430", "none")
+MSP430_MCU("msp430g2212", "msp430", "none")
+MSP430_MCU("msp430g2312", "msp430", "none")
+MSP430_MCU("msp430g2412", "msp430", "none")
+MSP430_MCU("msp430g2152", "msp430", "none")
+MSP430_MCU("msp430g2252", "msp430", "none")
+MSP430_MCU("msp430g2352", "msp430", "none")
+MSP430_MCU("msp430g2452", "msp430", "none")
+MSP430_MCU("msp430g2113", "msp430", "none")
+MSP430_MCU("msp430g2213", "msp430", "none")
+MSP430_MCU("msp430g2313", "msp430", "none")
+MSP430_MCU("msp430g2413", "msp430", "none")
+MSP430_MCU("msp430g2513", "msp430", "none")
+MSP430_MCU("msp430g2153", "msp430", "none")
+MSP430_MCU("msp430g2253", "msp430", "none")
+MSP430_MCU("msp430g2353", "msp430", "none")
+MSP430_MCU("msp430g2453", "msp430", "none")
+MSP430_MCU("msp430g2553", "msp430", "none")
+MSP430_MCU("msp430g2203", "msp430", "none")
+MSP430_MCU("msp430g2303", "msp430", "none")
+MSP430_MCU("msp430g2403", "msp430", "none")
+MSP430_MCU("msp430g2233", "msp430", "none")
+MSP430_MCU("msp430g2333", "msp430", "none")
+MSP430_MCU("msp430g2433", "msp430", "none")
+MSP430_MCU("msp430g2533", "msp430", "none")
+MSP430_MCU("msp430tch5e", "msp430", "none")
+MSP430_MCU("msp430g2444", "msp430", "none")
+MSP430_MCU("msp430g2544", "msp430", "none")
+MSP430_MCU("msp430g2744", "msp430", "none")
+MSP430_MCU("msp430g2755", "msp430", "none")
+MSP430_MCU("msp430g2855", "msp430", "none")
+MSP430_MCU("msp430g2955", "msp430", "none")
+MSP430_MCU("msp430g2230", "msp430", "none")
+MSP430_MCU("msp430g2210", "msp430", "none")
+MSP430_MCU("msp430bt5190", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5857", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5858", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5859", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5847", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr58471", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5848", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5849", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5867", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr58671", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5868", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5869", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5957", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5958", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5959", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5947", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr59471", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5948", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5949", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5967", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5968", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5969", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr59691", "msp430xv2", "32bit")
+MSP430_MCU("msp430i2020", "msp430", "16bit")
+MSP430_MCU("msp430i2021", "msp430", "16bit")
+MSP430_MCU("msp430i2030", "msp430", "16bit")
+MSP430_MCU("msp430i2031", "msp430", "16bit")
+MSP430_MCU("msp430i2040", "msp430", "16bit")
+MSP430_MCU("msp430i2041", "msp430", "16bit")
+MSP430_MCU("rf430frl152h", "msp430", "none")
+MSP430_MCU("rf430frl153h", "msp430", "none")
+MSP430_MCU("rf430frl154h", "msp430", "none")
+MSP430_MCU("rf430frl152h_rom", "msp430", "none")
+MSP430_MCU("rf430frl153h_rom", "msp430", "none")
+MSP430_MCU("rf430frl154h_rom", "msp430", "none")
+MSP430_MCU("rf430f5175", "msp430xv2", "32bit")
+MSP430_MCU("rf430f5155", "msp430xv2", "32bit")
+MSP430_MCU("rf430f5144", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr69271", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr68791", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr69791", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6927", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6928", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6877", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6977", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6879", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6979", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr58891", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr68891", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr59891", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr69891", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5887", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5888", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5889", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6887", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6888", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6889", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5986", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5987", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5988", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5989", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6987", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6988", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6989", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5922", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5870", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5970", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5872", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5972", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6820", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6920", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6822", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6922", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6870", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6970", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6872", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6972", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr59221", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr58721", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr59721", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr68221", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr69221", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr68721", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr69721", "msp430xv2", "32bit")
+MSP430_MCU("msp430sl5438a", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr4131", "msp430xv2", "none")
+MSP430_MCU("msp430fr4132", "msp430xv2", "none")
+MSP430_MCU("msp430fr4133", "msp430xv2", "none")
+MSP430_MCU("msp430fr2032", "msp430xv2", "none")
+MSP430_MCU("msp430fr2033", "msp430xv2", "none")
+MSP430_MCU("msp430fr2110", "msp430xv2", "none")
+MSP430_MCU("msp430fr2111", "msp430xv2", "none")
+MSP430_MCU("msp430fr2310", "msp430xv2", "none")
+MSP430_MCU("msp430fr2311", "msp430xv2", "none")
+MSP430_MCU("msp430fr2433", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2532", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2533", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2632", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2633", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5252", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5253", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5254", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5255", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5256", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5257", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5258", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5259", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5962", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5964", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5992", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5994", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr59941", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2100", "msp430xv2", "none")
+MSP430_MCU("msp430fr2000", "msp430xv2", "none")
+MSP430_MCU("msp430fr2355", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2155", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2353", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2153", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2522", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2512", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2422", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2676", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2476", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2675", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2673", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2475", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2672", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6043", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5043", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6041", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr60431", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr5041", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr50431", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6005", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6047", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6037", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6045", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr60471", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6035", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr6007", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr60371", "msp430xv2", "32bit")
 
 // Generic MCUs
-MSP430_MCU("msp430i2xxgeneric")
+MSP430_MCU("msp430i2xxgeneric", "msp430", "none")
 
 #undef MSP430_MCU
-#undef MSP430_MCU_FEAT
diff --git a/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py b/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py
index 3ae6fdd9d5c650..d93468c8ce11b4 100755
--- a/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py
+++ b/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py
@@ -17,11 +17,17 @@
 import sys
 
 DEVICE_COLUMN = 0
+CPU_COLUMN = 1
 MULTIPLIER_COLUMN = 3
 
-MULTIPLIER_SW = "0"
-MULTIPLIER_HW_16 = ("1", "2")
-MULTIPLIER_HW_32 = ("4", "8")
+CPUS = {"0": "msp430", "1": "msp430x", "2": "msp430xv2"}
+MULTIPLIERS = {
+    "0": "none",
+    "1": "16bit",
+    "2": "16bit",
+    "4": "32bit",
+    "8": "32bit",
+}
 
 PREFIX = """//===--- MSP430Target.def - MSP430 Feature/Processor Database----*- C++ -*-===//
 //
@@ -39,22 +45,17 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef MSP430_MCU_FEAT
-#define MSP430_MCU_FEAT(NAME, HWMULT) MSP430_MCU(NAME)
-#endif
-
 #ifndef MSP430_MCU
-#define MSP430_MCU(NAME)
+#define MSP430_MCU(NAME, CPU, HWMULT)
 #endif
 
 """
 
 SUFFIX = """
 // Generic MCUs
-MSP430_MCU("msp430i2xxgeneric")
+MSP430_MCU("msp430i2xxgeneric", "msp430", "none")
 
 #undef MSP430_MCU
-#undef MSP430_MCU_FEAT
 """
 
 
@@ -69,9 +70,7 @@ def csv2def(csv_path, def_path):
     "type def_path: str
     """
 
-    mcus_multiplier_sw = []
-    mcus_multiplier_hw_16 = []
-    mcus_multiplier_hw_32 = []
+    mcus = []
     version = "unknown"
 
     with open(csv_path) as csv_file:
@@ -82,6 +81,7 @@ def csv2def(csv_path, def_path):
                 continue
 
             if row[DEVICE_COLUMN] == "# Device Name":
+                assert row[CPU_COLUMN] == "CPU_TYPE", "File format changed"
                 assert row[MULTIPLIER_COLUMN] == "MPY_TYPE", "File format changed"
                 break
 
@@ -91,30 +91,21 @@ def csv2def(csv_path, def_path):
         for row in csv_reader:
             if row[DEVICE_COLUMN].endswith("generic"):
                 continue
-            if row[MULTIPLIER_COLUMN] == MULTIPLIER_SW:
-                mcus_multiplier_sw.append(row[DEVICE_COLUMN])
-            elif row[MULTIPLIER_COLUMN] in MULTIPLIER_HW_16:
-                mcus_multiplier_hw_16.append(row[DEVICE_COLUMN])
-            elif row[MULTIPLIER_COLUMN] in MULTIPLIER_HW_32:
-                mcus_multiplier_hw_32.append(row[DEVICE_COLUMN])
-            else:
-                assert 0, "Unknown multiplier type"
+            assert row[CPU_COLUMN] in CPUS, "Unknown CPU type"
+            assert row[MULTIPLIER_COLUMN] in MULTIPLIERS, "Unknown multiplier type"
+            mcus.append(
+                (
+                    row[DEVICE_COLUMN],
+                    CPUS[row[CPU_COLUMN]],
+                    MULTIPLIERS[row[MULTIPLIER_COLUMN]],
+                )
+            )
 
     with open(def_path, "w") as def_file:
         def_file.write(PREFIX.format(version))
 
-        for mcu in mcus_multiplier_sw:
-            def_file.write(f'MSP430_MCU("{mcu}")\n')
-
-        def_file.write("\n// With 16-bit hardware multiplier\n")
-
-        for mcu in mcus_multiplier_hw_16:
-            def_file.write(f'MSP430_MCU_FEAT("{mcu}", "16bit")\n')
-
-        def_file.write("\n// With 32-bit hardware multiplier\n")
-
-        for mcu in mcus_multiplier_hw_32:
-            def_file.write(f'MSP430_MCU_FEAT("{mcu}", "32bit")\n')
+        for name, cpu, hwmult in mcus:
+            def_file.write(f'MSP430_MCU("{name}", "{cpu}", "{hwmult}")\n')
 
         def_file.write(SUFFIX)
 
diff --git a/clang/lib/Driver/ToolChains/MSP430.cpp b/clang/lib/Driver/ToolChains/MSP430.cpp
index d543637c311d2f..4bd12d1e130e53 100644
--- a/clang/lib/Driver/ToolChains/MSP430.cpp
+++ b/clang/lib/Driver/ToolChains/MSP430.cpp
@@ -24,7 +24,7 @@ using namespace llvm::opt;
 
 static bool isSupportedMCU(const StringRef MCU) {
   return llvm::StringSwitch<bool>(MCU)
-#define MSP430_MCU(NAME) .Case(NAME, true)
+#define MSP430_MCU(NAME, CPU, HWMULT) .Case(NAME, true)
 #include "clang/Basic/MSP430Target.def"
       .Default(false);
 }
@@ -34,7 +34,7 @@ static StringRef getSupportedHWMult(const Arg *MCU) {
     return "none";
 
   return llvm::StringSwitch<StringRef>(MCU->getValue())
-#define MSP430_MCU_FEAT(NAME, HWMULT) .Case(NAME, HWMULT)
+#define MSP430_MCU(NAME, CPU, HWMULT) .Case(NAME, HWMULT)
 #include "clang/Basic/MSP430Target.def"
       .Default("none");
 }

>From 2edcaf7086d3ce6ce139d5720f4b8768750a042c Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m at pm.me>
Date: Thu, 1 Oct 2026 10:42:19 +0200
Subject: [PATCH 2/6] [MSP430][Clang] Select f5series hwmult for 5xx/6xx MCUs

Adds a new hwmult variant called f5series. The script now maps the HWMPY
value of 8 to this variant. This is important because the f5series
hardware multiplier has a different base address compared to older MPY32
support.

Also added new tests with a newer target containing a f5series hardware
multiplier. The auto mode will now also correctly map to include f5series
support if the MCU supports this.

Assisted-by: Claude Code (Claude Opus 5.5)
---
 clang/include/clang/Basic/MSP430Target.def    | 710 +++++++++---------
 .../Basic/Target/MSP430/gen-msp430-def.py     |   2 +-
 clang/test/Driver/msp430-hwmult.c             |   2 +
 clang/test/Driver/msp430-toolchain.c          |   4 +
 4 files changed, 362 insertions(+), 356 deletions(-)

diff --git a/clang/include/clang/Basic/MSP430Target.def b/clang/include/clang/Basic/MSP430Target.def
index cea5c2b038972d..6549cf0d7a91ef 100644
--- a/clang/include/clang/Basic/MSP430Target.def
+++ b/clang/include/clang/Basic/MSP430Target.def
@@ -199,252 +199,252 @@ MSP430_MCU("msp430fg4616", "msp430x", "16bit")
 MSP430_MCU("msp430fg4617", "msp430x", "16bit")
 MSP430_MCU("msp430fg4618", "msp430x", "16bit")
 MSP430_MCU("msp430fg4619", "msp430x", "16bit")
-MSP430_MCU("msp430f5418", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5419", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5435", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5436", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5437", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5438", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5418a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5419a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5435a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5436a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5437a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5438a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5212", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5213", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5214", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5217", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5218", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5219", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5222", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5223", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5224", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5227", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5228", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5229", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5232", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5234", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5237", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5239", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5242", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5244", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5247", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5249", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5304", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5308", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5309", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5310", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5340", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5341", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5342", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5324", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5325", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5326", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5327", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5328", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5329", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5500", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5501", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5502", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5503", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5504", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5505", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5506", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5507", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5508", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5509", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5510", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5513", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5514", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5515", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5517", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5519", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5521", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5522", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5524", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5525", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5526", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5527", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5528", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5529", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5418", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5419", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5435", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5436", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5437", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5438", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5418a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5419a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5435a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5436a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5437a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5438a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5212", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5213", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5214", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5217", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5218", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5219", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5222", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5223", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5224", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5227", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5228", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5229", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5232", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5234", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5237", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5239", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5242", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5244", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5247", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5249", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5304", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5308", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5309", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5310", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5340", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5341", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5342", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5324", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5325", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5326", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5327", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5328", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5329", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5500", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5501", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5502", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5503", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5504", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5505", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5506", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5507", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5508", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5509", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5510", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5513", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5514", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5515", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5517", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5519", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5521", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5522", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5524", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5525", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5526", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5527", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5528", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5529", "msp430xv2", "f5series")
 MSP430_MCU("msp430p112", "msp430", "none")
 MSP430_MCU("msp430p313", "msp430", "none")
 MSP430_MCU("msp430p315", "msp430", "none")
 MSP430_MCU("msp430p315s", "msp430", "none")
 MSP430_MCU("msp430p325", "msp430", "none")
 MSP430_MCU("msp430p337", "msp430", "16bit")
-MSP430_MCU("cc430f5133", "msp430xv2", "32bit")
-MSP430_MCU("cc430f5135", "msp430xv2", "32bit")
-MSP430_MCU("cc430f5137", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6125", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6126", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6127", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6135", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6137", "msp430xv2", "32bit")
-MSP430_MCU("cc430f5123", "msp430xv2", "32bit")
-MSP430_MCU("cc430f5125", "msp430xv2", "32bit")
-MSP430_MCU("cc430f5143", "msp430xv2", "32bit")
-MSP430_MCU("cc430f5145", "msp430xv2", "32bit")
-MSP430_MCU("cc430f5147", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6143", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6145", "msp430xv2", "32bit")
-MSP430_MCU("cc430f6147", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5333", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5335", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5336", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5338", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5630", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5631", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5632", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5633", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5634", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5635", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5636", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5637", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5638", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6433", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6435", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6436", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6438", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6630", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6631", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6632", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6633", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6634", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6635", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6636", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6637", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6638", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5358", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5359", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5658", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5659", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6458", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6459", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6658", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6659", "msp430xv2", "32bit")
-MSP430_MCU("msp430fg6425", "msp430xv2", "32bit")
-MSP430_MCU("msp430fg6426", "msp430xv2", "32bit")
-MSP430_MCU("msp430fg6625", "msp430xv2", "32bit")
-MSP430_MCU("msp430fg6626", "msp430xv2", "32bit")
+MSP430_MCU("cc430f5133", "msp430xv2", "f5series")
+MSP430_MCU("cc430f5135", "msp430xv2", "f5series")
+MSP430_MCU("cc430f5137", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6125", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6126", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6127", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6135", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6137", "msp430xv2", "f5series")
+MSP430_MCU("cc430f5123", "msp430xv2", "f5series")
+MSP430_MCU("cc430f5125", "msp430xv2", "f5series")
+MSP430_MCU("cc430f5143", "msp430xv2", "f5series")
+MSP430_MCU("cc430f5145", "msp430xv2", "f5series")
+MSP430_MCU("cc430f5147", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6143", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6145", "msp430xv2", "f5series")
+MSP430_MCU("cc430f6147", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5333", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5335", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5336", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5338", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5630", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5631", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5632", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5633", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5634", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5635", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5636", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5637", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5638", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6433", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6435", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6436", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6438", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6630", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6631", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6632", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6633", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6634", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6635", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6636", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6637", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6638", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5358", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5359", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5658", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5659", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6458", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6459", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6658", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6659", "msp430xv2", "f5series")
+MSP430_MCU("msp430fg6425", "msp430xv2", "f5series")
+MSP430_MCU("msp430fg6426", "msp430xv2", "f5series")
+MSP430_MCU("msp430fg6625", "msp430xv2", "f5series")
+MSP430_MCU("msp430fg6626", "msp430xv2", "f5series")
 MSP430_MCU("msp430l092", "msp430", "none")
 MSP430_MCU("msp430c091", "msp430", "none")
 MSP430_MCU("msp430c092", "msp430", "none")
-MSP430_MCU("msp430f5131", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5151", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5171", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5132", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5152", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5172", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6720", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6721", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6723", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6724", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6725", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6726", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6730", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6731", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6733", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6734", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6735", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6736", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67621", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67641", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6720a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6721a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6723a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6724a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6725a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6726a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6730a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6731a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6733a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6734a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6735a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6736a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67621a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67641a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67451", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67651", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67751", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67461", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67661", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67761", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67471", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67671", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67771", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67481", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67681", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67781", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67491", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67691", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67791", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6745", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6765", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6775", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6746", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6766", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6776", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6747", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6767", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6777", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6748", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6768", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6778", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6749", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6769", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6779", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67451a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67651a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67751a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67461a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67661a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67761a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67471a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67671a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67771a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67481a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67681a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67781a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67491a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67691a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f67791a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6745a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6765a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6775a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6746a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6766a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6776a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6747a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6767a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6777a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6748a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6768a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6778a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6749a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6769a", "msp430xv2", "32bit")
-MSP430_MCU("msp430f6779a", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5720", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5721", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5722", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5723", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5724", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5725", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5726", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5727", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5728", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5729", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5730", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5731", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5732", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5733", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5734", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5735", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5736", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5737", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5738", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5739", "msp430xv2", "32bit")
+MSP430_MCU("msp430f5131", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5151", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5171", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5132", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5152", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5172", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6720", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6721", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6723", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6724", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6725", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6726", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6730", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6731", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6733", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6734", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6735", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6736", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67621", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67641", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6720a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6721a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6723a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6724a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6725a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6726a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6730a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6731a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6733a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6734a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6735a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6736a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67621a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67641a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67451", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67651", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67751", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67461", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67661", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67761", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67471", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67671", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67771", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67481", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67681", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67781", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67491", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67691", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67791", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6745", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6765", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6775", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6746", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6766", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6776", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6747", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6767", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6777", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6748", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6768", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6778", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6749", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6769", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6779", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67451a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67651a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67751a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67461a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67661a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67761a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67471a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67671a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67771a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67481a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67681a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67781a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67491a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67691a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f67791a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6745a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6765a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6775a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6746a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6766a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6776a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6747a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6767a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6777a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6748a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6768a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6778a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6749a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6769a", "msp430xv2", "f5series")
+MSP430_MCU("msp430f6779a", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5720", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5721", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5722", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5723", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5724", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5725", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5726", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5727", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5728", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5729", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5730", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5731", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5732", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5733", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5734", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5735", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5736", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5737", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5738", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5739", "msp430xv2", "f5series")
 MSP430_MCU("msp430g2211", "msp430", "none")
 MSP430_MCU("msp430g2201", "msp430", "none")
 MSP430_MCU("msp430g2111", "msp430", "none")
@@ -505,29 +505,29 @@ MSP430_MCU("msp430g2855", "msp430", "none")
 MSP430_MCU("msp430g2955", "msp430", "none")
 MSP430_MCU("msp430g2230", "msp430", "none")
 MSP430_MCU("msp430g2210", "msp430", "none")
-MSP430_MCU("msp430bt5190", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5857", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5858", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5859", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5847", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr58471", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5848", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5849", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5867", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr58671", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5868", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5869", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5957", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5958", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5959", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5947", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr59471", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5948", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5949", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5967", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5968", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5969", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr59691", "msp430xv2", "32bit")
+MSP430_MCU("msp430bt5190", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5857", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5858", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5859", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5847", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr58471", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5848", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5849", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5867", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr58671", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5868", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5869", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5957", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5958", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5959", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5947", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr59471", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5948", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5949", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5967", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5968", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5969", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr59691", "msp430xv2", "f5series")
 MSP430_MCU("msp430i2020", "msp430", "16bit")
 MSP430_MCU("msp430i2021", "msp430", "16bit")
 MSP430_MCU("msp430i2030", "msp430", "16bit")
@@ -540,56 +540,56 @@ MSP430_MCU("rf430frl154h", "msp430", "none")
 MSP430_MCU("rf430frl152h_rom", "msp430", "none")
 MSP430_MCU("rf430frl153h_rom", "msp430", "none")
 MSP430_MCU("rf430frl154h_rom", "msp430", "none")
-MSP430_MCU("rf430f5175", "msp430xv2", "32bit")
-MSP430_MCU("rf430f5155", "msp430xv2", "32bit")
-MSP430_MCU("rf430f5144", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr69271", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr68791", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr69791", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6927", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6928", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6877", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6977", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6879", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6979", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr58891", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr68891", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr59891", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr69891", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5887", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5888", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5889", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6887", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6888", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6889", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5986", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5987", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5988", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5989", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6987", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6988", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6989", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5922", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5870", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5970", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5872", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5972", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6820", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6920", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6822", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6922", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6870", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6970", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6872", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6972", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr59221", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr58721", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr59721", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr68221", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr69221", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr68721", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr69721", "msp430xv2", "32bit")
-MSP430_MCU("msp430sl5438a", "msp430xv2", "32bit")
+MSP430_MCU("rf430f5175", "msp430xv2", "f5series")
+MSP430_MCU("rf430f5155", "msp430xv2", "f5series")
+MSP430_MCU("rf430f5144", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr69271", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr68791", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr69791", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6927", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6928", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6877", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6977", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6879", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6979", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr58891", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr68891", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr59891", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr69891", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5887", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5888", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5889", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6887", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6888", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6889", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5986", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5987", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5988", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5989", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6987", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6988", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6989", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5922", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5870", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5970", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5872", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5972", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6820", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6920", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6822", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6922", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6870", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6970", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6872", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6972", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr59221", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr58721", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr59721", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr68221", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr69221", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr68721", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr69721", "msp430xv2", "f5series")
+MSP430_MCU("msp430sl5438a", "msp430xv2", "f5series")
 MSP430_MCU("msp430fr4131", "msp430xv2", "none")
 MSP430_MCU("msp430fr4132", "msp430xv2", "none")
 MSP430_MCU("msp430fr4133", "msp430xv2", "none")
@@ -599,53 +599,53 @@ MSP430_MCU("msp430fr2110", "msp430xv2", "none")
 MSP430_MCU("msp430fr2111", "msp430xv2", "none")
 MSP430_MCU("msp430fr2310", "msp430xv2", "none")
 MSP430_MCU("msp430fr2311", "msp430xv2", "none")
-MSP430_MCU("msp430fr2433", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2532", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2533", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2632", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2633", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5252", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5253", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5254", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5255", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5256", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5257", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5258", "msp430xv2", "32bit")
-MSP430_MCU("msp430f5259", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5962", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5964", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5992", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5994", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr59941", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2433", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2532", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2533", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2632", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2633", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5252", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5253", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5254", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5255", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5256", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5257", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5258", "msp430xv2", "f5series")
+MSP430_MCU("msp430f5259", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5962", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5964", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5992", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5994", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr59941", "msp430xv2", "f5series")
 MSP430_MCU("msp430fr2100", "msp430xv2", "none")
 MSP430_MCU("msp430fr2000", "msp430xv2", "none")
-MSP430_MCU("msp430fr2355", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2155", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2353", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2153", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2522", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2512", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2422", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2676", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2476", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2675", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2673", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2475", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr2672", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6043", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5043", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6041", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr60431", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr5041", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr50431", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6005", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6047", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6037", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6045", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr60471", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6035", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr6007", "msp430xv2", "32bit")
-MSP430_MCU("msp430fr60371", "msp430xv2", "32bit")
+MSP430_MCU("msp430fr2355", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2155", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2353", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2153", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2522", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2512", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2422", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2676", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2476", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2675", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2673", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2475", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr2672", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6043", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5043", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6041", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr60431", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr5041", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr50431", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6005", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6047", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6037", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6045", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr60471", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6035", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr6007", "msp430xv2", "f5series")
+MSP430_MCU("msp430fr60371", "msp430xv2", "f5series")
 
 // Generic MCUs
 MSP430_MCU("msp430i2xxgeneric", "msp430", "none")
diff --git a/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py b/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py
index d93468c8ce11b4..2ade78e2eccfac 100755
--- a/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py
+++ b/clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py
@@ -26,7 +26,7 @@
     "1": "16bit",
     "2": "16bit",
     "4": "32bit",
-    "8": "32bit",
+    "8": "f5series",
 }
 
 PREFIX = """//===--- MSP430Target.def - MSP430 Feature/Processor Database----*- C++ -*-===//
diff --git a/clang/test/Driver/msp430-hwmult.c b/clang/test/Driver/msp430-hwmult.c
index 3ba6bfcdce5f76..ee263fffbe6f06 100644
--- a/clang/test/Driver/msp430-hwmult.c
+++ b/clang/test/Driver/msp430-hwmult.c
@@ -21,6 +21,7 @@
 // CHECK-32: "-target-feature" "+hwmult32"
 
 // RUN: %clang  -### --target=msp430 %s -mhwmult=f5series 2>&1 | FileCheck --check-prefix=CHECK-F5 %s
+// RUN: %clang  -### --target=msp430 %s -mmcu=msp430f5529 2>&1 | FileCheck --check-prefix=CHECK-F5 %s
 // CHECK-F5: "-target-feature" "+hwmultf5"
 
 // RUN: not %clang  -### --target=msp430 %s -mhwmult=rrr 2>&1 | FileCheck --check-prefix=INVL-ARG %s
@@ -39,4 +40,5 @@
 // RUN: %clang  -### --target=msp430 %s -mhwmult=16bit -mmcu=msp430f4783 2>&1 | FileCheck --check-prefix=WRN-MISMCH %s
 // RUN: %clang  -### --target=msp430 %s -mhwmult=32bit -mmcu=msp430f147 2>&1 | FileCheck --check-prefix=WRN-MISMCH %s
 // RUN: %clang  -### --target=msp430 %s -mhwmult=f5series -mmcu=msp430f4783 2>&1 | FileCheck --check-prefix=WRN-MISMCH %s
+// RUN: %clang  -### --target=msp430 %s -mhwmult=32bit -mmcu=msp430f5529 2>&1 | FileCheck --check-prefix=WRN-MISMCH %s
 // WRN-MISMCH: warning: the given MCU supports {{.*}} hardware multiply, but '-mhwmult' is set to {{.*}}
diff --git a/clang/test/Driver/msp430-toolchain.c b/clang/test/Driver/msp430-toolchain.c
index 3c3042b482ef26..45010deb40a54d 100644
--- a/clang/test/Driver/msp430-toolchain.c
+++ b/clang/test/Driver/msp430-toolchain.c
@@ -253,6 +253,10 @@
 // RUN:   | FileCheck -check-prefix=HWMult-32BIT %s
 // HWMult-32BIT: "--start-group" "-lmul_32"
 
+// RUN: %clang -### %s --target=msp430 -mmcu=msp430f5529 --sysroot="" 2>&1 \
+// RUN:   | FileCheck -check-prefix=HWMult-F5 %s
+// RUN: %clang -### %s --target=msp430 -mmcu=msp430f5529 -mhwmult=auto --sysroot="" 2>&1 \
+// RUN:   | FileCheck -check-prefix=HWMult-F5 %s
 // RUN: %clang -### %s --target=msp430 -mhwmult=f5series --sysroot="" 2>&1 \
 // RUN:   | FileCheck -check-prefix=HWMult-F5 %s
 // HWMult-F5: "--start-group" "-lmul_f5"

>From 2621c4be2aa9bd7895f21e4628cfaacdbaf81be1 Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m at pm.me>
Date: Thu, 1 Oct 2026 13:52:04 +0200
Subject: [PATCH 3/6] [MSP430][Clang] MSP430X Target CPU selection

- Pass -target-cpu to LLVM, taken from `-mcpu` or derived from `-mmcu`.
- Unknown `-mcpu` values for MSP430 are rejected now
- `-mcpu=msp430x` and `-mcpu=msp430xv2` are both mapped to msp430x. The
  newer revision does not change the generated code, only CPU cycle
  counts
- The information can also be derived from `-mmcu` only using the target
  table, which contains the CPU type.
- Added `MSP430X` and `__MSP430X__` defines. The `__MSP430X__` define matches GCC
- Updated GCC Multilib finder to use the GCC root libraries (MSP430X) for
  the MSP430X CPU target. Otherwise, it will still use the /430
  subdirectory like before.

Based on https://reviews.llvm.org/D109174.

Co-authored-by: Jozef Lawrynowicz <jozefl.opensrc at gmail.com>
Assisted-by: Claude Code (Claude Opus 5.5)
---
 clang/lib/Basic/Targets/MSP430.cpp         |  2 ++
 clang/lib/Basic/Targets/MSP430.h           | 18 +++++++++++++-
 clang/lib/Driver/ToolChains/CommonArgs.cpp |  3 +++
 clang/lib/Driver/ToolChains/Gnu.cpp        | 23 +++++++++---------
 clang/lib/Driver/ToolChains/MSP430.cpp     | 18 ++++++++++++++
 clang/lib/Driver/ToolChains/MSP430.h       |  2 ++
 clang/test/Driver/msp430-cpu.c             | 25 +++++++++++++++++++
 clang/test/Driver/msp430-toolchain.c       | 28 ++++++++++++++++++++++
 clang/test/Preprocessor/msp430-defs.c      |  9 +++++++
 9 files changed, 115 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/Driver/msp430-cpu.c
 create mode 100644 clang/test/Preprocessor/msp430-defs.c

diff --git a/clang/lib/Basic/Targets/MSP430.cpp b/clang/lib/Basic/Targets/MSP430.cpp
index 844f5d3af70379..989927a8c5ab69 100644
--- a/clang/lib/Basic/Targets/MSP430.cpp
+++ b/clang/lib/Basic/Targets/MSP430.cpp
@@ -29,5 +29,7 @@ void MSP430TargetInfo::getTargetDefines(const LangOptions &Opts,
                                         MacroBuilder &Builder) const {
   Builder.defineMacro("MSP430");
   Builder.defineMacro("__MSP430__");
+  if (CPU == "msp430x")
+    Builder.defineMacro("__MSP430X__");
   // FIXME: defines for different 'flavours' of MCU
 }
diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h
index 96a243ef70fae5..fceb7c6e68e201 100644
--- a/clang/lib/Basic/Targets/MSP430.h
+++ b/clang/lib/Basic/Targets/MSP430.h
@@ -23,6 +23,7 @@ namespace targets {
 
 class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo {
   static const char *const GCCRegNames[];
+  std::string CPU;
 
 public:
   MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -55,10 +56,25 @@ class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo {
     return {};
   }
 
+  bool isValidCPUName(StringRef Name) const override {
+    return Name == "msp430" || Name == "msp430x";
+  }
+
+  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override {
+    Values.append({"msp430", "msp430x"});
+  }
+
+  bool setCPU(StringRef Name) override {
+    if (!isValidCPUName(Name))
+      return false;
+    CPU = Name;
+    return true;
+  }
+
   bool allowsLargerPreferedTypeAlignment() const override { return false; }
 
   bool hasFeature(StringRef Feature) const override {
-    return Feature == "msp430";
+    return Feature == "msp430" || (Feature == "msp430x" && CPU == "msp430x");
   }
 
   ArrayRef<const char *> getGCCRegNames() const override;
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 7c832ef405fa51..8f844dcfdb17b3 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -810,6 +810,9 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
     return std::string(CPUName);
   }
 
+  case llvm::Triple::msp430:
+    return msp430::getMSP430TargetCPU(Args);
+
   case llvm::Triple::nvptx:
   case llvm::Triple::nvptx64:
     if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 90fc71c147364d..0a58b251d0e693 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -1529,20 +1529,19 @@ static bool findMSP430Multilibs(const Driver &D,
                                 StringRef Path, const ArgList &Args,
                                 DetectedMultilibs &Result) {
   FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS());
-  MultilibBuilder WithoutExceptions =
-      MultilibBuilder("/430").flag("-exceptions", /*Disallow=*/true);
-  MultilibBuilder WithExceptions =
-      MultilibBuilder("/430/exceptions").flag("-exceptions");
-
-  // FIXME: when clang starts to support msp430x ISA additional logic
-  // to select between multilib must be implemented
-  // MultilibBuilder MSP430xMultilib = MultilibBuilder("/large");
-
-  Result.Multilibs.push_back(WithoutExceptions.makeMultilib());
-  Result.Multilibs.push_back(WithExceptions.makeMultilib());
-  Result.Multilibs.FilterOut(NonExistent);
+  // The MSP430X libraries are in the root, the plain MSP430 ones in /430.
+  // FIXME: Add the /large multilibs once LLVM supports the large memory model.
+  Result.Multilibs =
+      MultilibSetBuilder()
+          .Either(MultilibBuilder().flag("-msp430x"),
+                  MultilibBuilder("/430").flag("-msp430x", /*Disallow=*/true))
+          .Maybe(MultilibBuilder("/exceptions").flag("-exceptions"))
+          .makeMultilibSet()
+          .FilterOut(NonExistent);
 
   Multilib::flags_list Flags;
+  std::string CPU = tools::getCPUName(D, Args, TargetTriple);
+  addMultilibFlag(CPU == "msp430x", "-msp430x", Flags);
   addMultilibFlag(Args.hasFlag(options::OPT_fexceptions,
                                options::OPT_fno_exceptions, false),
                   "-exceptions", Flags);
diff --git a/clang/lib/Driver/ToolChains/MSP430.cpp b/clang/lib/Driver/ToolChains/MSP430.cpp
index 4bd12d1e130e53..5259e0721bdb26 100644
--- a/clang/lib/Driver/ToolChains/MSP430.cpp
+++ b/clang/lib/Driver/ToolChains/MSP430.cpp
@@ -13,6 +13,7 @@
 #include "clang/Driver/InputInfo.h"
 #include "clang/Driver/Multilib.h"
 #include "clang/Options/Options.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/Path.h"
 
@@ -52,6 +53,23 @@ static StringRef getHWMultLib(const ArgList &Args) {
       .Default("-lmul_none");
 }
 
+static bool isMSP430X(StringRef CPU) {
+  return CPU == "msp430x" || CPU == "msp430xv2";
+}
+
+std::string msp430::getMSP430TargetCPU(const ArgList &Args) {
+  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+    return isMSP430X(A->getValue()) ? "msp430x" : A->getValue();
+  if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ)) {
+    StringRef CPU = llvm::StringSwitch<StringRef>(A->getValue())
+#define MSP430_MCU(NAME, CPU, HWMULT) .Case(NAME, CPU)
+#include "clang/Basic/MSP430Target.def"
+                        .Default("");
+    return isMSP430X(CPU) ? "msp430x" : CPU.str();
+  }
+  return "";
+}
+
 void msp430::getMSP430TargetFeatures(const Driver &D, const ArgList &Args,
                                      std::vector<StringRef> &Features) {
   const Arg *MCU = Args.getLastArg(options::OPT_mmcu_EQ);
diff --git a/clang/lib/Driver/ToolChains/MSP430.h b/clang/lib/Driver/ToolChains/MSP430.h
index 865bcfb7cd3da6..3539c62430f675 100644
--- a/clang/lib/Driver/ToolChains/MSP430.h
+++ b/clang/lib/Driver/ToolChains/MSP430.h
@@ -80,6 +80,8 @@ class LLVM_LIBRARY_VISIBILITY Linker final : public Tool {
 
 void getMSP430TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
                              std::vector<llvm::StringRef> &Features);
+std::string getMSP430TargetCPU(const llvm::opt::ArgList &Args);
+
 } // end namespace msp430
 } // end namespace tools
 } // end namespace driver
diff --git a/clang/test/Driver/msp430-cpu.c b/clang/test/Driver/msp430-cpu.c
new file mode 100644
index 00000000000000..d09272436f5700
--- /dev/null
+++ b/clang/test/Driver/msp430-cpu.c
@@ -0,0 +1,25 @@
+// RUN: %clang -### -c %s --target=msp430 2>&1 \
+// RUN:   | FileCheck -check-prefix=NO-CPU %s
+// NO-CPU-NOT: "-target-cpu"
+
+// RUN: %clang -### -c %s --target=msp430 -mcpu=msp430 2>&1 \
+// RUN:   | FileCheck -check-prefix=MSP430 %s
+// RUN: %clang -### -c %s --target=msp430 -mmcu=msp430c111 2>&1 \
+// RUN:   | FileCheck -check-prefix=MSP430 %s
+// MSP430: "-cc1"{{.*}} "-target-cpu" "msp430"
+
+// msp430xv2 is accepted for GCC compatibility and treated as msp430x.
+// RUN: %clang -### -c %s --target=msp430 -mcpu=msp430x 2>&1 \
+// RUN:   | FileCheck -check-prefix=MSP430X %s
+// RUN: %clang -### -c %s --target=msp430 -mcpu=msp430xv2 2>&1 \
+// RUN:   | FileCheck -check-prefix=MSP430X %s
+// RUN: %clang -### -c %s --target=msp430 -mmcu=msp430f2617 2>&1 \
+// RUN:   | FileCheck -check-prefix=MSP430X %s
+// RUN: %clang -### -c %s --target=msp430 -mmcu=msp430f5529 2>&1 \
+// RUN:   | FileCheck -check-prefix=MSP430X %s
+// MSP430X: "-cc1"{{.*}} "-target-cpu" "msp430x"
+
+// RUN: not %clang -c %s --target=msp430 -mcpu=not-a-cpu -o /dev/null 2>&1 \
+// RUN:   | FileCheck -check-prefix=INVALID %s
+// INVALID: error: unknown target CPU 'not-a-cpu'
+// INVALID-NEXT: note: valid target CPU values are: msp430, msp430x
diff --git a/clang/test/Driver/msp430-toolchain.c b/clang/test/Driver/msp430-toolchain.c
index 45010deb40a54d..45de069b0aafe9 100644
--- a/clang/test/Driver/msp430-toolchain.c
+++ b/clang/test/Driver/msp430-toolchain.c
@@ -126,6 +126,34 @@
 // LIBS-EXC-NEG-NOT: "{{.*}}/430"
 // LIBS-EXC-NEG-NOT: "{{.*}}430/crt{{.*}}"
 
+// The MSP430X multilibs are in the root, not in /430.
+// RUN: %clang -### %s --target=msp430 -mcpu=msp430x -rtlib=libgcc \
+// RUN:   --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1
+// RUN: FileCheck -check-prefix=LIBS-430X-POS %s < %t
+// RUN: FileCheck -check-prefix=LIBS-430X-NEG %s < %t
+// RUN: %clang -### %s --target=msp430 -mmcu=msp430f5529 -rtlib=libgcc \
+// RUN:   --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1
+// RUN: FileCheck -check-prefix=LIBS-430X-POS %s < %t
+// RUN: FileCheck -check-prefix=LIBS-430X-NEG %s < %t
+// LIBS-430X-POS: "{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib{{/|\\\\}}crt0.o"
+// LIBS-430X-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1{{/|\\\\}}crtbegin_no_eh.o"
+// LIBS-430X-POS: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1{{/|\\\\}}"
+// LIBS-430X-POS: "-L{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib{{/|\\\\}}"
+// LIBS-430X-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1{{/|\\\\}}crtend_no_eh.o"
+// LIBS-430X-NEG-NOT: /430
+// LIBS-430X-NEG-NOT: /exceptions
+
+// RUN: %clang -### %s --target=msp430 -mcpu=msp430x -rtlib=libgcc -fexceptions \
+// RUN:   --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1
+// RUN: FileCheck -check-prefix=LIBS-430X-EXC-POS %s < %t
+// RUN: FileCheck -check-prefix=LIBS-430X-EXC-NEG %s < %t
+// LIBS-430X-EXC-POS: "{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib/exceptions{{/|\\\\}}crt0.o"
+// LIBS-430X-EXC-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/exceptions{{/|\\\\}}crtbegin.o"
+// LIBS-430X-EXC-POS: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/exceptions"
+// LIBS-430X-EXC-POS: "-L{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib/exceptions"
+// LIBS-430X-EXC-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/exceptions{{/|\\\\}}crtend.o"
+// LIBS-430X-EXC-NEG-NOT: /430
+
 // RUN: %clang -### %s --target=msp430 -rtlib=libgcc \
 // RUN:   -fstack-protector  --sysroot="%S/Inputs/basic_msp430_tree" 2>&1 \
 // RUN:   | FileCheck -check-prefix=LIBS-SSP %s
diff --git a/clang/test/Preprocessor/msp430-defs.c b/clang/test/Preprocessor/msp430-defs.c
new file mode 100644
index 00000000000000..6eea5c6e7521cc
--- /dev/null
+++ b/clang/test/Preprocessor/msp430-defs.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple msp430 -E -dM %s -o - \
+// RUN:   | FileCheck -check-prefix=MSP430 %s
+// RUN: %clang_cc1 -triple msp430 -target-cpu msp430 -E -dM %s -o - \
+// RUN:   | FileCheck -check-prefix=MSP430 %s
+// MSP430-NOT: #define __MSP430X__
+
+// RUN: %clang_cc1 -triple msp430 -target-cpu msp430x -E -dM %s -o - \
+// RUN:   | FileCheck -check-prefix=MSP430X %s
+// MSP430X: #define __MSP430X__ 1

>From 7bd8735e7a2ed7738f86cc1d1614fce079377b7d Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m at pm.me>
Date: Thu, 1 Oct 2026 15:56:25 +0200
Subject: [PATCH 4/6] [MSP430] Add assembler support for MSP430X shift
 instructions

- Add RRCM, RRAM, RRUM, RLAM, RRCX, RRAX, RRUX and RLAX for -mcpu=msp430x
- Encode extended instructions with the extension word in the low bits,
  matching their order in memory
- Disassemble MSP430X address instructions and extension words
- Report an error for instructions that need a disabled CPU feature.
  They were silently dropped before

Based on https://reviews.llvm.org/D110723, reworked for current
TableGen.

Co-authored-by: Jozef Lawrynowicz <jozefl.opensrc at gmail.com>
Assisted-by: Claude Opus 5.5 <noreply at anthropic.com>
---
 .../MSP430/AsmParser/MSP430AsmParser.cpp      |  21 +++-
 .../Disassembler/MSP430Disassembler.cpp       |  56 +++++++++-
 .../MCTargetDesc/MSP430MCCodeEmitter.cpp      |  18 ++++
 llvm/lib/Target/MSP430/MSP430InstrFormats.td  |  95 ++++++++++++++++
 llvm/lib/Target/MSP430/MSP430InstrInfo.td     |   9 ++
 .../Target/MSP430/MSP430InstrInfoExtended.td  |  84 +++++++++++++++
 llvm/lib/Target/MSP430/MSP430Subtarget.h      |   2 +
 .../Disassembler/MSP430/msp430x-invalid.txt   |  13 +++
 llvm/test/MC/Disassembler/MSP430/msp430x.txt  |  18 ++++
 llvm/test/MC/MSP430/msp430x-feature.s         |   9 ++
 llvm/test/MC/MSP430/shifts-430x-invalid.s     |  23 ++++
 llvm/test/MC/MSP430/shifts-430x.s             | 101 ++++++++++++++++++
 12 files changed, 443 insertions(+), 6 deletions(-)
 create mode 100644 llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
 create mode 100644 llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
 create mode 100644 llvm/test/MC/Disassembler/MSP430/msp430x.txt
 create mode 100644 llvm/test/MC/MSP430/msp430x-feature.s
 create mode 100644 llvm/test/MC/MSP430/shifts-430x-invalid.s
 create mode 100644 llvm/test/MC/MSP430/shifts-430x.s

diff --git a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
index 65a545fc415d5a..e22f520b4a2d65 100644
--- a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
+++ b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
@@ -163,11 +163,8 @@ class MSP430Operand : public MCParsedAsmOperand {
   bool isPostIndReg()     const { return Kind == k_PostIndReg; }
 
   bool isCGImm() const {
-    if (Kind != k_Imm)
-      return false;
-
     int64_t Val;
-    if (!Imm->evaluateAsAbsolute(Val))
+    if (!isImm() || !Imm->evaluateAsAbsolute(Val))
       return false;
     
     if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
@@ -176,6 +173,19 @@ class MSP430Operand : public MCParsedAsmOperand {
     return false;
   }
 
+  /// Shift count of the MSP430X multi-bit shifts (RRAM, RRUM, RLAM). It is
+  /// encoded as count - 1 in a 2-bit field, so only 1 to 4 is valid.
+  bool isRpt2Imm() const {
+    int64_t Val;
+    if (!isImm() || !Imm->evaluateAsAbsolute(Val))
+      return false;
+
+    if (Val >= 1 && Val <= 4)
+      return true;
+
+    return false;
+  }
+
   StringRef getToken() const {
     assert(Kind == k_Tok && "Invalid access!");
     return Tok;
@@ -266,6 +276,9 @@ bool MSP430AsmParser::matchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
     return false;
   case Match_MnemonicFail:
     return Error(Loc, "invalid instruction mnemonic");
+  case Match_MissingFeature:
+    return Error(Loc,
+                 "instruction requires a CPU feature not currently enabled");
   case Match_InvalidOperand: {
     SMLoc ErrorLoc = Loc;
     if (ErrorInfo != ~0U) {
diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
index e6666e8cafdf9d..3f473bc1504801 100644
--- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
+++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
@@ -44,6 +44,10 @@ class MSP430Disassembler : public MCDisassembler {
                                 ArrayRef<uint8_t> Bytes, uint64_t Address,
                                 raw_ostream &CStream) const;
 
+  DecodeStatus getInstructionX(MCInst &MI, uint64_t &Size,
+                               ArrayRef<uint8_t> Bytes, uint64_t Address,
+                               raw_ostream &CStream) const;
+
 public:
   MSP430Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
       : MCDisassembler(STI, Ctx) {}
@@ -119,6 +123,15 @@ static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address,
   return MCDisassembler::Success;
 }
 
+/// Decode the 2-bit shift count of RRCM, RRAM, RRUM and RLAM. It is stored as
+/// count - 1.
+static DecodeStatus decodeRpt2Imm(MCInst &MI, uint64_t Bits, uint64_t Address,
+                                  const MCDisassembler *Decoder) {
+  int64_t Imm = Bits + 1;
+  MI.addOperand(MCOperand::createImm(Imm));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits,
                                      uint64_t Address,
                                      const MCDisassembler *Decoder) {
@@ -353,6 +366,37 @@ DecodeStatus MSP430Disassembler::getInstructionCJ(MCInst &MI, uint64_t &Size,
   return DecodeStatus::Success;
 }
 
+static bool isExtensionWord(uint64_t Word) { return (Word & 0xf800) == 0x1800; }
+
+DecodeStatus MSP430Disassembler::getInstructionX(MCInst &MI, uint64_t &Size,
+                                                 ArrayRef<uint8_t> Bytes,
+                                                 uint64_t Address,
+                                                 raw_ostream &CStream) const {
+  uint64_t Insn = support::endian::read16le(Bytes.data());
+  unsigned Words = 1;
+  if (isExtensionWord(Insn)) {
+    if (Bytes.size() < 4) {
+      Size = 2;
+      return DecodeStatus::Fail;
+    }
+    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
+    Words = 2;
+  }
+
+  // MSP430X32 decodes the extension word together with the following Format I
+  // or II word. Each combination is its own instruction, like RRCX_16 or
+  // ADDX16rr, so the plain Format I and II tables are not used here.
+  const uint8_t *DecoderTable =
+      Words == 2 ? DecoderTableMSP430X32 : DecoderTableMSP430X16;
+  DecodeStatus Result =
+      decodeInstruction(DecoderTable, MI, Insn, Address, this, STI);
+  // The word after an extension word is a valid Format I or II instruction on
+  // its own. Skip it on failure too, so it is not shown without the extension
+  // word.
+  Size = Words * 2;
+  return Result;
+}
+
 DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
                                                 ArrayRef<uint8_t> Bytes,
                                                 uint64_t Address,
@@ -362,10 +406,18 @@ DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
     return MCDisassembler::Fail;
   }
 
+  // The first word selects the instruction format:
+  //   0x0000-0x0fff  MSP430X address instructions
+  //   0x1000-0x17ff  Format II
+  //   0x1800-0x1fff  MSP430X extension word, followed by a Format I or II word
+  //   0x2000-0x3fff  Jumps
+  //   0x4000-0xffff  Format I
   uint64_t Insn = support::endian::read16le(Bytes.data());
-  unsigned Opc = fieldFromInstruction(Insn, 13, 3);
-  switch (Opc) {
+  unsigned FormatBits = fieldFromInstruction(Insn, 13, 3);
+  switch (FormatBits) {
   case 0:
+    if (!(Insn & 0x1000) || isExtensionWord(Insn))
+      return getInstructionX(MI, Size, Bytes, Address, CStream);
     return getInstructionII(MI, Size, Bytes, Address, CStream);
   case 1:
     return getInstructionCJ(MI, Size, Bytes, Address, CStream);
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
index f018bdbeb0bfbc..0436434658049e 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
@@ -64,6 +64,12 @@ class MSP430MCCodeEmitter : public MCCodeEmitter {
                            SmallVectorImpl<MCFixup> &Fixups,
                            const MCSubtargetInfo &STI) const;
 
+  /// Encode the repetition count for a 430X extended format exception
+  /// instruction.
+  unsigned getRpt2ImmOpValue(const MCInst &MI, unsigned Op,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
   unsigned getCCOpValue(const MCInst &MI, unsigned Op,
                         SmallVectorImpl<MCFixup> &Fixups,
                         const MCSubtargetInfo &STI) const;
@@ -192,6 +198,18 @@ unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op,
   }
 }
 
+unsigned
+MSP430MCCodeEmitter::getRpt2ImmOpValue(const MCInst &MI, unsigned Op,
+                                       SmallVectorImpl<MCFixup> &Fixups,
+                                       const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(Op);
+  assert(MO.isImm() && "expr operand expected");
+
+  int64_t Imm = MO.getImm();
+  assert((Imm >= 1 && Imm <= 4) && "invalid repetition count");
+  return Imm - 1;
+}
+
 unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
                                            SmallVectorImpl<MCFixup> &Fixups,
                                            const MCSubtargetInfo &STI) const {
diff --git a/llvm/lib/Target/MSP430/MSP430InstrFormats.td b/llvm/lib/Target/MSP430/MSP430InstrFormats.td
index 0e784aa4ff9144..f850100cd2eddc 100644
--- a/llvm/lib/Target/MSP430/MSP430InstrFormats.td
+++ b/llvm/lib/Target/MSP430/MSP430InstrFormats.td
@@ -28,6 +28,13 @@ class DestMode<bit val> {
 def DstReg      : DestMode<0>;   // r
 def DstMem      : DestMode<1>;   // m
 
+class ALKind<bit val> {
+  bit Value = val;
+}
+
+def ALAddr : ALKind<0>;
+def ALWord : ALKind<1>;
+
 // Generic MSP430 Format
 class MSP430Inst<dag outs, dag ins, int size, string asmstr> : Instruction {
   field bits<48> Inst;
@@ -432,6 +439,94 @@ class CJForm<dag outs, dag ins, string asmstr, list<dag> pattern>
   let Inst{9-0} = dst;
 }
 
+// RRCM, RRAM, RRUM and RLAM. Single-word MSP430X instructions with their own
+// layout in the Format II opcode space, without an extension word. TI calls
+// them Format II exceptions.
+class IIExtExcRotForm<bits<2> opcode, ALKind al,
+                      dag outs, dag ins, string asmstr, list<dag> pattern>
+  : MSP430Inst<outs, ins, 2, asmstr> {
+  let Pattern = pattern;
+  let DecoderNamespace = "MSP430X";
+
+  bits<4> rd;
+  bits<2> cnt;
+
+  let Inst{15-12} = 0b0000;
+  let Inst{11-10} = cnt;
+  let Inst{9-8}   = opcode;
+  let Inst{7-5}   = 0b010;
+  let Inst{4}     = al.Value;
+  let Inst{3-0}   = rd;
+}
+
+class IIExtExcRotForm16<bits<2> opcode,
+                        dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IIExtExcRotForm<opcode, ALWord, outs, ins, asmstr, pattern>;
+
+// MSP430X extended instructions in register mode.
+//
+// The extension word precedes the instruction word in memory, so it occupies
+// Inst{15-0} and the instruction word is in Inst{31-16}.
+//
+// FIXME: Add the non-register mode, which is needed for 20-bit memory
+// operands.
+class ExtRegForm<bit zc, bit rpt, ALKind al,
+                 dag outs, dag ins, string asmstr, list<dag> pattern>
+  : MSP430Inst<outs, ins, 4, asmstr> {
+  let Pattern = pattern;
+  let DecoderNamespace = "MSP430X";
+
+  bits<4> cnt = 0;
+
+  let Inst{15-9} = 0b0001100;
+  let Inst{8}    = zc;
+  let Inst{7}    = rpt;
+  let Inst{6}    = al.Value;
+  let Inst{5-4}  = 0b00;
+  let Inst{3-0}  = cnt;
+}
+
+// Same layout as IIForm, moved behind the extension word.
+class IIExtRegForm<bits<3> opcode, bit bw, bit zc, bit rpt,
+                   dag outs, dag ins, string asmstr, list<dag> pattern>
+  : ExtRegForm<zc, rpt, ALWord, outs, ins, asmstr, pattern> {
+  bits<4> rs;
+
+  let Inst{31-26} = 0b000100;
+  let Inst{25-23} = opcode;
+  let Inst{22}    = bw;
+  let Inst{21-20} = SrcReg.Value;
+  let Inst{19-16} = rs;
+}
+
+// Same layout as IForm, moved behind the extension word.
+class IExtRegForm<bits<4> opcode, bit bw, bit zc, bit rpt,
+                  dag outs, dag ins, string asmstr, list<dag> pattern>
+  : ExtRegForm<zc, rpt, ALWord, outs, ins, asmstr, pattern> {
+  bits<4> rs;
+  bits<4> rd;
+
+  let Inst{31-28} = opcode;
+  let Inst{27-24} = rs;
+  let Inst{23}    = DstReg.Value;
+  let Inst{22}    = bw;
+  let Inst{21-20} = SrcReg.Value;
+  let Inst{19-16} = rd;
+}
+
+class II8rExtended<bits<3> opcode, bit zc, bit rpt,
+                   dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IIExtRegForm<opcode, 1, zc, rpt, outs, ins, asmstr, pattern>;
+class II16rExtended<bits<3> opcode, bit zc, bit rpt,
+                    dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IIExtRegForm<opcode, 0, zc, rpt, outs, ins, asmstr, pattern>;
+class I8rExtended<bits<4> opcode, bit zc, bit rpt,
+                  dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IExtRegForm<opcode, 1, zc, rpt, outs, ins, asmstr, pattern>;
+class I16rExtended<bits<4> opcode, bit zc, bit rpt,
+                   dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IExtRegForm<opcode, 0, zc, rpt, outs, ins, asmstr, pattern>;
+
 // Pseudo instructions
 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
   : MSP430Inst<outs, ins, 0, asmstr> {
diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfo.td b/llvm/lib/Target/MSP430/MSP430InstrInfo.td
index f25c96e3109a9d..3e870be0c0f588 100644
--- a/llvm/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/llvm/lib/Target/MSP430/MSP430InstrInfo.td
@@ -12,6 +12,13 @@
 
 include "MSP430InstrFormats.td"
 
+//===----------------------------------------------------------------------===//
+// Feature predicates.
+//===----------------------------------------------------------------------===//
+
+def HasMSP430X : Predicate<"Subtarget->hasMSP430X()">,
+                 AssemblerPredicate<(all_of FeatureX), "MSP430X">;
+
 //===----------------------------------------------------------------------===//
 // Type Constraints.
 //===----------------------------------------------------------------------===//
@@ -990,3 +997,5 @@ def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
 def : Pat<(MSP430cmp (trunc (and_su GR16:$src, GR16:$src2)), 0),
           (BIT8rr (EXTRACT_SUBREG GR16:$src, subreg_8bit),
                   (EXTRACT_SUBREG GR16:$src2, subreg_8bit))>;
+
+include "MSP430InstrInfoExtended.td"
diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td b/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
new file mode 100644
index 00000000000000..d56b42875955d3
--- /dev/null
+++ b/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
@@ -0,0 +1,84 @@
+//===-- MSP430InstrInfoExtended.td - MSP430X Instruction defs -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the MSP430X extended instructions in TableGen format.
+//
+//===----------------------------------------------------------------------===//
+
+// TODO: Most extended instructions have a .A version that enables 20-bit
+// operands. This requires support the large memory model to be implemented.
+//
+// Only the extended instructions that are useful in the small memory model
+// (16-bit pointers) are implemented so far. Instructions like MOVX are not
+// required in the small memory model, and have increased size/cycle count
+// compared to their 430 versions.
+
+def Rpt2ImmAsmOperand : AsmOperandClass {
+  let Name = "Rpt2Imm";
+  let RenderMethod = "addImmOperands";
+}
+
+def rpt2imm : Operand<i8>,
+              ImmLeaf<i8, [{return Imm >= 1 && Imm <= 4;}]> {
+  let ParserMatchClass = Rpt2ImmAsmOperand;
+  let EncoderMethod = "getRpt2ImmOpValue";
+  let DecoderMethod = "decodeRpt2Imm";
+}
+
+//===----------------------------------------------------------------------===//
+//  Shift Instructions
+//
+let Predicates = [HasMSP430X] in {
+let Constraints = "$rs = $rd", Defs = [SR] in {
+  multiclass IIExtExcRot<string Mnemonic, bits<2> OpCode,
+                         list<Register> uses> {
+    let Uses = uses in
+    def _16 : IIExtExcRotForm16<OpCode,
+                                (outs GR16:$rd), (ins GR16:$rs, rpt2imm:$cnt),
+                                !strconcat(Mnemonic, "\t$cnt, $rd"), []>;
+  }
+
+  defm RRCM : IIExtExcRot<"rrcm", 0b00, [SR]>;
+  defm RRAM : IIExtExcRot<"rram", 0b01, []>;
+  defm RRUM : IIExtExcRot<"rrum", 0b11, []>;
+  defm RLAM : IIExtExcRot<"rlam", 0b10, []>;
+
+  multiclass IIExtRot<string Mnemonic, bits<3> OpCode, bit ZC,
+                      list<Register> uses> {
+    let Uses = uses in {
+    def _8  :  II8rExtended<OpCode, ZC, 0,
+                            (outs GR8:$rd), (ins GR8:$rs),
+                            !strconcat(Mnemonic, ".b\t$rd"), []>;
+    def _16 : II16rExtended<OpCode, ZC, 0,
+                            (outs GR16:$rd), (ins GR16:$rs),
+                            !strconcat(Mnemonic, "\t$rd"), []>;
+    }
+  }
+  defm RRCX : IIExtRot<"rrcx", 0b000, 0, [SR]>;
+  defm RRAX : IIExtRot<"rrax", 0b010, 0, []>;
+  // RRUX is encoded as RRCX with the ZC flag set.
+  defm RRUX : IIExtRot<"rrux", 0b000, 1, []>;
+
+} // Defs = [SR], Constraints = "$rs = $rd"
+
+//===----------------------------------------------------------------------===//
+//  Arithmetic Instructions
+//
+let Defs = [SR], Constraints = "$src2 = $rd" in {
+  def ADDX8rr  : I8rExtended<0b0101, 0, 0,
+                             (outs GR8:$rd), (ins GR8:$src2, GR8:$rs),
+                             "addx.b\t$rs, $rd", []>;
+  def ADDX16rr : I16rExtended<0b0101, 0, 0,
+                              (outs GR16:$rd), (ins GR16:$src2, GR16:$rs),
+                              "addx\t$rs, $rd", []>;
+}
+
+// Alias printing is disabled for the same reason as for RLA.
+def RLAX8r  : InstAlias<"rlax.b\t$dst", (ADDX8rr  GR8:$dst,  GR8:$dst),  0>;
+def RLAX16r : InstAlias<"rlax\t$dst",   (ADDX16rr GR16:$dst, GR16:$dst), 0>;
+} // Predicates = [HasMSP430X]
diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.h b/llvm/lib/Target/MSP430/MSP430Subtarget.h
index 4cb5c9b7467e50..b301922b96aa94 100644
--- a/llvm/lib/Target/MSP430/MSP430Subtarget.h
+++ b/llvm/lib/Target/MSP430/MSP430Subtarget.h
@@ -61,6 +61,8 @@ class MSP430Subtarget : public MSP430GenSubtargetInfo {
   bool hasHWMult32() const { return HWMultMode == HWMult32; }
   bool hasHWMultF5() const { return HWMultMode == HWMultF5; }
 
+  bool hasMSP430X() const { return ExtendedInsts; }
+
   const TargetFrameLowering *getFrameLowering() const override {
     return &FrameLowering;
   }
diff --git a/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt b/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
new file mode 100644
index 00000000000000..0ac8a359e23880
--- /dev/null
+++ b/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
@@ -0,0 +1,13 @@
+# RUN: llvm-mc -disassemble %s -triple=msp430 -mcpu=msp430x 2>&1 >/dev/null \
+# RUN:   | FileCheck %s --check-prefix=WARN
+# RUN: llvm-mc -disassemble %s -triple=msp430 -mcpu=msp430x 2>/dev/null \
+# RUN:   | FileCheck %s
+
+# An unsupported extended instruction (rpt #4 + rrax r12) is skipped as a
+# whole. Its instruction word must not show up as rra r12.
+# CHECK: rram #1, r12
+# CHECK-NEXT: rram #2, r12
+# WARN: :[[@LINE+2]]:1: warning: invalid instruction encoding
+0x5c 0x01
+0x43 0x18 0x0c 0x11
+0x5c 0x05
diff --git a/llvm/test/MC/Disassembler/MSP430/msp430x.txt b/llvm/test/MC/Disassembler/MSP430/msp430x.txt
new file mode 100644
index 00000000000000..0ee456ef92dd31
--- /dev/null
+++ b/llvm/test/MC/Disassembler/MSP430/msp430x.txt
@@ -0,0 +1,18 @@
+# RUN: llvm-mc -disassemble %s -triple=msp430 -mcpu=msp430x | FileCheck %s
+
+0x5c 0x01                     # CHECK: rram #1, r12
+0x5c 0x0d                     # CHECK: rram #4, r12
+0x55 0x07                     # CHECK: rrum #2, r5
+0x5f 0x0a                     # CHECK: rlam #3, r15
+0x5c 0x00                     # CHECK: rrcm #1, r12
+0x56 0x0c                     # CHECK: rrcm #4, r6
+0x40 0x18 0x0c 0x11           # CHECK: rrax r12
+0x40 0x18 0x4c 0x11           # CHECK: rrax.b r12
+0x40 0x18 0x0c 0x10           # CHECK: rrcx r12
+0x40 0x18 0x48 0x10           # CHECK: rrcx.b r8
+0x40 0x19 0x0c 0x10           # CHECK: rrux r12
+0x40 0x19 0x47 0x10           # CHECK: rrux.b r7
+0x40 0x18 0x0c 0x5c           # CHECK: addx r12, r12
+0x40 0x18 0x49 0x59           # CHECK: addx.b r9, r9
+0x40 0x18 0x0c 0x55           # CHECK: addx r5, r12
+0x40 0x18 0x47 0x55           # CHECK: addx.b r5, r7
diff --git a/llvm/test/MC/MSP430/msp430x-feature.s b/llvm/test/MC/MSP430/msp430x-feature.s
new file mode 100644
index 00000000000000..6d6ece721088e3
--- /dev/null
+++ b/llvm/test/MC/MSP430/msp430x-feature.s
@@ -0,0 +1,9 @@
+// MSP430X instructions require -mcpu=msp430x.
+// RUN: not llvm-mc -triple msp430 %s 2>&1 | FileCheck %s
+
+  rram #1, r12
+// CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  rrax r12
+// CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  rlax r12
+// CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
diff --git a/llvm/test/MC/MSP430/shifts-430x-invalid.s b/llvm/test/MC/MSP430/shifts-430x-invalid.s
new file mode 100644
index 00000000000000..c333b40e2304d4
--- /dev/null
+++ b/llvm/test/MC/MSP430/shifts-430x-invalid.s
@@ -0,0 +1,23 @@
+// Tests to check for incorrect use of MSP430X shift instructions.
+// RUN: not llvm-mc --triple=msp430 -mcpu=msp430x < %s 2>&1 | FileCheck %s
+
+foo:
+// Check for an error when the repetition count is too large.
+  rrum #5, r12
+  rram #5, r12
+  rlam #5, r12
+  rrcm #5, r12
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+
+// Check for an error when RxxX shifts have a shift amount operand.
+  rrcx #3, r12
+  rrux #3, r12
+  rrax #3, r12
+  rlax #3, r12
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
diff --git a/llvm/test/MC/MSP430/shifts-430x.s b/llvm/test/MC/MSP430/shifts-430x.s
new file mode 100644
index 00000000000000..ccf2d8ec9b6bd6
--- /dev/null
+++ b/llvm/test/MC/MSP430/shifts-430x.s
@@ -0,0 +1,101 @@
+// Test the encoding of shift instructions for the 430X CPU.
+
+// RUN: llvm-mc -triple msp430 -mcpu=msp430x -show-encoding < %s | FileCheck %s
+rxxm:
+	rrum	#1, r12                         ; encoding: [0x5c,0x03]
+	rrum	#2, r12                         ; encoding: [0x5c,0x07]
+	rrum	#3, r12                         ; encoding: [0x5c,0x0b]
+	rrum	#4, r12                         ; encoding: [0x5c,0x0f]
+
+	rram	#1, r12                         ; encoding: [0x5c,0x01]
+	rram	#2, r12                         ; encoding: [0x5c,0x05]
+	rram	#3, r12                         ; encoding: [0x5c,0x09]
+	rram	#4, r12                         ; encoding: [0x5c,0x0d]
+
+	rlam	#1, r12                         ; encoding: [0x5c,0x02]
+	rlam	#2, r12                         ; encoding: [0x5c,0x06]
+	rlam	#3, r12                         ; encoding: [0x5c,0x0a]
+	rlam	#4, r12                         ; encoding: [0x5c,0x0e]
+
+	rrcm	#1, r12                         ; encoding: [0x5c,0x00]
+	rrcm	#2, r12                         ; encoding: [0x5c,0x04]
+	rrcm	#3, r12                         ; encoding: [0x5c,0x08]
+	rrcm	#4, r12                         ; encoding: [0x5c,0x0c]
+
+// CHECK-LABEL: rxxm:
+// CHECK-NEXT: rrum	#1, r12                         ; encoding: [0x5c,0x03]
+// CHECK: rrum	#2, r12                         ; encoding: [0x5c,0x07]
+// CHECK: rrum	#3, r12                         ; encoding: [0x5c,0x0b]
+// CHECK: rrum	#4, r12                         ; encoding: [0x5c,0x0f]
+
+// CHECK: rram	#1, r12                         ; encoding: [0x5c,0x01]
+// CHECK: rram	#2, r12                         ; encoding: [0x5c,0x05]
+// CHECK: rram	#3, r12                         ; encoding: [0x5c,0x09]
+// CHECK: rram	#4, r12                         ; encoding: [0x5c,0x0d]
+
+// CHECK: rlam	#1, r12                         ; encoding: [0x5c,0x02]
+// CHECK: rlam	#2, r12                         ; encoding: [0x5c,0x06]
+// CHECK: rlam	#3, r12                         ; encoding: [0x5c,0x0a]
+// CHECK: rlam	#4, r12                         ; encoding: [0x5c,0x0e]
+
+// CHECK: rrcm	#1, r12                         ; encoding: [0x5c,0x00]
+// CHECK: rrcm	#2, r12                         ; encoding: [0x5c,0x04]
+// CHECK: rrcm	#3, r12                         ; encoding: [0x5c,0x08]
+// CHECK: rrcm	#4, r12                         ; encoding: [0x5c,0x0c]
+
+rrcx:
+  rrcx r12
+
+// CHECK-LABEL: rrcx:
+// CHECK-NEXT: rrcx	r12                             ; encoding: [0x40,0x18,0x0c,0x10]
+
+rrcx_b:
+  rrcx.b r12
+
+// CHECK-LABEL: rrcx_b:
+// CHECK-NEXT: rrcx.b	r12                             ; encoding: [0x40,0x18,0x4c,0x10]
+
+rrux:
+  rrux r12
+
+// CHECK-LABEL: rrux:
+// CHECK-NEXT: rrux	r12                             ; encoding: [0x40,0x19,0x0c,0x10]
+
+rrux_b:
+  rrux.b r12
+
+// CHECK-LABEL: rrux_b:
+// CHECK-NEXT: rrux.b	r12                             ; encoding: [0x40,0x19,0x4c,0x10]
+
+rrax:
+  rrax r12
+
+// CHECK-LABEL: rrax:
+// CHECK-NEXT: rrax	r12                             ; encoding: [0x40,0x18,0x0c,0x11]
+
+rrax_b:
+  rrax.b r12
+
+// CHECK-LABEL: rrax_b:
+// CHECK-NEXT: rrax.b	r12                             ; encoding: [0x40,0x18,0x4c,0x11]
+
+// RLAX is an alias of ADDX with both registers equal. Alias printing is
+// disabled, so it prints as ADDX.
+rlax:
+  rlax r12
+
+// CHECK-LABEL: rlax:
+// CHECK-NEXT: addx	r12, r12                        ; encoding: [0x40,0x18,0x0c,0x5c]
+
+rlax_b:
+  rlax.b r12
+
+// CHECK-LABEL: rlax_b:
+// CHECK-NEXT: addx.b	r12, r12                        ; encoding: [0x40,0x18,0x4c,0x5c]
+
+// ADDX with different registers must not be treated as RLAX.
+addx:
+  addx r5, r12
+
+// CHECK-LABEL: addx:
+// CHECK-NEXT: addx	r5, r12                         ; encoding: [0x40,0x18,0x0c,0x55]

>From fd1e345aef6a2998ea7ec9e2a17432c180e9f0cd Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m at pm.me>
Date: Wed, 14 Oct 2026 19:13:40 +0200
Subject: [PATCH 5/6] [MSP430] Add assembler support for MSP430X PUSHM and POPM

- Add PUSHM and POPM for -mcpu=msp430x. They push or pop a range of up
  to 16 registers, counting down from the given register
- POPM encodes the lowest register of the range, PUSHM the highest
- Disassemble 0x1400-0x17ff with the MSP430X decoder table. The plain
  Format II decoder read the count bits as an addressing mode
- Reject register ranges that extend below r0
- Add the 4-bit count operand rpt4imm (1 to 16)

Codegen support for callee-saved registers follows separately.

Based on https://reviews.llvm.org/D110240.

Co-authored-by: Jozef Lawrynowicz <jozefl.opensrc at gmail.com>
Assisted-by: Claude Opus 5.5 <noreply at anthropic.com>
---
 .../MSP430/AsmParser/MSP430AsmParser.cpp      |  35 ++++++
 .../Disassembler/MSP430Disassembler.cpp       |  45 ++++---
 .../MCTargetDesc/MSP430MCCodeEmitter.cpp      |  36 ++++++
 llvm/lib/Target/MSP430/MSP430InstrFormats.td  |  23 ++++
 .../Target/MSP430/MSP430InstrInfoExtended.td  |  38 +++++-
 .../Disassembler/MSP430/msp430x-invalid.txt   |   4 +
 llvm/test/MC/Disassembler/MSP430/msp430x.txt  |   6 +
 llvm/test/MC/MSP430/msp430x-feature.s         |   4 +
 llvm/test/MC/MSP430/pushm-popm-invalid.s      |  37 ++++++
 llvm/test/MC/MSP430/pushm-popm.s              | 110 ++++++++++++++++++
 10 files changed, 324 insertions(+), 14 deletions(-)
 create mode 100644 llvm/test/MC/MSP430/pushm-popm-invalid.s
 create mode 100644 llvm/test/MC/MSP430/pushm-popm.s

diff --git a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
index e22f520b4a2d65..36c677ab9b3dc5 100644
--- a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
+++ b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
@@ -56,6 +56,8 @@ class MSP430AsmParser : public MCTargetAsmParser {
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
 
+  bool validateInstruction(const MCInst &Inst, const OperandVector &Operands);
+
   bool parseJccInstruction(ParseInstructionInfo &Info, StringRef Name,
                            SMLoc NameLoc, OperandVector &Operands);
 
@@ -186,6 +188,18 @@ class MSP430Operand : public MCParsedAsmOperand {
     return false;
   }
 
+  /// Count from 1 to 16, encoded as count - 1 in a 4-bit field.
+  bool isRpt4Imm() const {
+    int64_t Val;
+    if (!isImm() || !Imm->evaluateAsAbsolute(Val))
+      return false;
+
+    if (Val >= 1 && Val <= 16)
+      return true;
+
+    return false;
+  }
+
   StringRef getToken() const {
     assert(Kind == k_Tok && "Invalid access!");
     return Tok;
@@ -271,6 +285,8 @@ bool MSP430AsmParser::matchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
 
   switch (MatchResult) {
   case Match_Success:
+    if (validateInstruction(Inst, Operands))
+      return true;
     Inst.setLoc(Loc);
     Out.emitInstruction(Inst, *STI);
     return false;
@@ -296,6 +312,25 @@ bool MSP430AsmParser::matchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
   }
 }
 
+bool MSP430AsmParser::validateInstruction(const MCInst &Inst,
+                                          const OperandVector &Operands) {
+  switch (Inst.getOpcode()) {
+  case MSP430::PUSHM16r:
+  case MSP430::POPM16r: {
+    // The range counts down from the given register, so it must not go below
+    // r0.
+    int64_t Count = Inst.getOperand(0).getImm();
+    MCRegister Reg = Inst.getOperand(1).getReg();
+    if (Count > getContext().getRegisterInfo()->getEncodingValue(Reg) + 1)
+      return Error(((MSP430Operand &)*Operands[2]).getStartLoc(),
+                   "register range extends below r0");
+    return false;
+  }
+  default:
+    return false;
+  }
+}
+
 // Auto-generated by TableGen
 static MCRegister MatchRegisterName(StringRef Name);
 static MCRegister MatchRegisterAltName(StringRef Name);
diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
index 3f473bc1504801..4b50daed3631e6 100644
--- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
+++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
@@ -123,10 +123,10 @@ static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address,
   return MCDisassembler::Success;
 }
 
-/// Decode the 2-bit shift count of RRCM, RRAM, RRUM and RLAM. It is stored as
-/// count - 1.
-static DecodeStatus decodeRpt2Imm(MCInst &MI, uint64_t Bits, uint64_t Address,
-                                  const MCDisassembler *Decoder) {
+/// Decode a count stored as count - 1. Used for the 2-bit shift count of RRCM,
+/// RRAM, RRUM and RLAM and the 4-bit register count of PUSHM and POPM.
+static DecodeStatus decodeRptImm(MCInst &MI, uint64_t Bits, uint64_t Address,
+                                 const MCDisassembler *Decoder) {
   int64_t Imm = Bits + 1;
   MI.addOperand(MCOperand::createImm(Imm));
   return MCDisassembler::Success;
@@ -146,6 +146,17 @@ static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits,
   return MCDisassembler::Success;
 }
 
+/// POPM encodes Rdst - n + 1 for Rdst, while PUSHM encodes Rdst. The count n
+/// is decoded before the register.
+static DecodeStatus decodePOPMRegOperand(MCInst &MI, uint64_t Bits,
+                                         uint64_t Address,
+                                         const MCDisassembler *Decoder) {
+  assert(MI.getNumOperands() == 1 && MI.getOperand(0).isImm() &&
+         "count must be decoded before the register");
+  int64_t Count = MI.getOperand(0).getImm();
+  return DecodeGR16RegisterClass(MI, (Bits & 15) + Count - 1, Address, Decoder);
+}
+
 #include "MSP430GenDisassemblerTables.inc"
 
 enum AddrMode {
@@ -406,19 +417,27 @@ DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
     return MCDisassembler::Fail;
   }
 
-  // The first word selects the instruction format:
-  //   0x0000-0x0fff  MSP430X address instructions
-  //   0x1000-0x17ff  Format II
-  //   0x1800-0x1fff  MSP430X extension word, followed by a Format I or II word
-  //   0x2000-0x3fff  Jumps
-  //   0x4000-0xffff  Format I
+  // The first word selects the decoder. MSP430X and Format II are interleaved
+  // below 0x2000. II* is a single-word MSP430X instruction with its own layout
+  // in the Format II opcode space (TI: Format II exception).
+  //
+  //   Range          Decoder  Format     Instructions
+  //   0x0000-0x0fff  X        addr, II*  MOVA, ADDA, ..., RRCM, RRAM, RLAM, ...
+  //   0x1000-0x13ff  II       II         RRC, SWPB, RRA, SXT, PUSH, CALL, RETI
+  //   0x1400-0x17ff  X        II*        PUSHM, POPM
+  //   0x1800-0x1fff  X        ext+I/II   RRCX, RRAX, ADDX, ...
+  //   0x2000-0x3fff  CJ       jump       JMP, JNE, ...
+  //   0x4000-0xffff  I        I          MOV, ADD, ...
+  //
+  // ext+I/II is an extension word followed by a Format I or II word.
   uint64_t Insn = support::endian::read16le(Bytes.data());
   unsigned FormatBits = fieldFromInstruction(Insn, 13, 3);
   switch (FormatBits) {
   case 0:
-    if (!(Insn & 0x1000) || isExtensionWord(Insn))
-      return getInstructionX(MI, Size, Bytes, Address, CStream);
-    return getInstructionII(MI, Size, Bytes, Address, CStream);
+    // 0x1000-0x13ff
+    if ((Insn & 0x1c00) == 0x1000)
+      return getInstructionII(MI, Size, Bytes, Address, CStream);
+    return getInstructionX(MI, Size, Bytes, Address, CStream);
   case 1:
     return getInstructionCJ(MI, Size, Bytes, Address, CStream);
   default:
diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
index 0436434658049e..36caa8ffcdcdc7 100644
--- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
+++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
@@ -70,10 +70,20 @@ class MSP430MCCodeEmitter : public MCCodeEmitter {
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
 
+  /// Encode a count from 1 to 16 in a 4-bit field.
+  unsigned getRpt4ImmOpValue(const MCInst &MI, unsigned Op,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
   unsigned getCCOpValue(const MCInst &MI, unsigned Op,
                         SmallVectorImpl<MCFixup> &Fixups,
                         const MCSubtargetInfo &STI) const;
 
+  /// POPM encodes Rdst - n + 1 for Rdst, while PUSHM encodes Rdst.
+  unsigned getPOPMRegOpValue(const MCInst &MI, unsigned Op,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
 public:
   MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
       : Ctx(ctx), MCII(MCII) {}
@@ -210,6 +220,18 @@ MSP430MCCodeEmitter::getRpt2ImmOpValue(const MCInst &MI, unsigned Op,
   return Imm - 1;
 }
 
+unsigned
+MSP430MCCodeEmitter::getRpt4ImmOpValue(const MCInst &MI, unsigned Op,
+                                       SmallVectorImpl<MCFixup> &Fixups,
+                                       const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(Op);
+  assert(MO.isImm() && "expr operand expected");
+
+  int64_t Imm = MO.getImm();
+  assert((Imm >= 1 && Imm <= 16) && "invalid repetition count");
+  return Imm - 1;
+}
+
 unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
                                            SmallVectorImpl<MCFixup> &Fixups,
                                            const MCSubtargetInfo &STI) const {
@@ -228,6 +250,20 @@ unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
   }
 }
 
+unsigned
+MSP430MCCodeEmitter::getPOPMRegOpValue(const MCInst &MI, unsigned Op,
+                                       SmallVectorImpl<MCFixup> &Fixups,
+                                       const MCSubtargetInfo &STI) const {
+  const MCOperand &CountMO = MI.getOperand(0);
+  const MCOperand &RegMO = MI.getOperand(Op);
+  assert(CountMO.isImm() && RegMO.isReg() && "unexpected POPM operands");
+
+  unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(RegMO.getReg());
+  int64_t Count = CountMO.getImm();
+  assert(Count >= 1 && Count <= int64_t(Reg) + 1 && "POPM range below r0");
+  return Reg - Count + 1;
+}
+
 MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII,
                                          MCContext &Ctx) {
   return new MSP430MCCodeEmitter(Ctx, MCII);
diff --git a/llvm/lib/Target/MSP430/MSP430InstrFormats.td b/llvm/lib/Target/MSP430/MSP430InstrFormats.td
index f850100cd2eddc..384315b030b95b 100644
--- a/llvm/lib/Target/MSP430/MSP430InstrFormats.td
+++ b/llvm/lib/Target/MSP430/MSP430InstrFormats.td
@@ -527,6 +527,29 @@ class I16rExtended<bits<4> opcode, bit zc, bit rpt,
                    dag outs, dag ins, string asmstr, list<dag> pattern>
   : IExtRegForm<opcode, 0, zc, rpt, outs, ins, asmstr, pattern>;
 
+// PUSHM and POPM. Single-word MSP430X instructions with their own layout in
+// the Format II opcode space, without an extension word. TI calls them Format
+// II exceptions.
+class IIExtExcPushPopForm<bit ispop, ALKind al,
+                          dag outs, dag ins, string asmstr, list<dag> pattern>
+  : MSP430Inst<outs, ins, 2, asmstr> {
+  let Pattern = pattern;
+  let DecoderNamespace = "MSP430X";
+
+  bits<4> cnt;
+  bits<4> rs;
+
+  let Inst{15-10} = 0b000101;
+  let Inst{9}     = ispop;
+  let Inst{8}     = al.Value;
+  let Inst{7-4}   = cnt;
+  let Inst{3-0}   = rs;
+}
+
+class IIExtExcPushPopForm16<bit ispop,
+                            dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IIExtExcPushPopForm<ispop, ALWord, outs, ins, asmstr, pattern>;
+
 // Pseudo instructions
 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
   : MSP430Inst<outs, ins, 0, asmstr> {
diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td b/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
index d56b42875955d3..d078531f7f0ffc 100644
--- a/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
+++ b/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
@@ -18,6 +18,9 @@
 // required in the small memory model, and have increased size/cycle count
 // compared to their 430 versions.
 
+//===----------------------------------------------------------------------===//
+//  Operands
+//
 def Rpt2ImmAsmOperand : AsmOperandClass {
   let Name = "Rpt2Imm";
   let RenderMethod = "addImmOperands";
@@ -27,7 +30,25 @@ def rpt2imm : Operand<i8>,
               ImmLeaf<i8, [{return Imm >= 1 && Imm <= 4;}]> {
   let ParserMatchClass = Rpt2ImmAsmOperand;
   let EncoderMethod = "getRpt2ImmOpValue";
-  let DecoderMethod = "decodeRpt2Imm";
+  let DecoderMethod = "decodeRptImm";
+}
+
+def Rpt4ImmAsmOperand : AsmOperandClass {
+  let Name = "Rpt4Imm";
+  let RenderMethod = "addImmOperands";
+}
+
+def rpt4imm : Operand<i8>,
+              ImmLeaf<i8, [{return Imm >= 1 && Imm <= 16;}]> {
+  let ParserMatchClass = Rpt4ImmAsmOperand;
+  let EncoderMethod = "getRpt4ImmOpValue";
+  let DecoderMethod = "decodeRptImm";
+}
+
+// POPM encodes Rdst - n + 1 for Rdst, while PUSHM encodes Rdst.
+def popmreg : RegisterOperand<GR16> {
+  let EncoderMethod = "getPOPMRegOpValue";
+  let DecoderMethod = "decodePOPMRegOperand";
 }
 
 //===----------------------------------------------------------------------===//
@@ -81,4 +102,19 @@ let Defs = [SR], Constraints = "$src2 = $rd" in {
 // Alias printing is disabled for the same reason as for RLA.
 def RLAX8r  : InstAlias<"rlax.b\t$dst", (ADDX8rr  GR8:$dst,  GR8:$dst),  0>;
 def RLAX16r : InstAlias<"rlax\t$dst",   (ADDX16rr GR16:$dst, GR16:$dst), 0>;
+
+//===----------------------------------------------------------------------===//
+//  Push/Pop Multiple Registers
+//
+// $rs is the highest register of the range. The other registers depend on the
+// count, so codegen must add them as implicit operands when it builds the
+// instruction.
+let Defs = [SP], Uses = [SP], hasSideEffects = 0 in {
+let mayStore = 1 in
+def PUSHM16r : IIExtExcPushPopForm16<0, (outs), (ins rpt4imm:$cnt, GR16:$rs),
+                                     "pushm\t$cnt, $rs", []>;
+let mayLoad = 1 in
+def POPM16r  : IIExtExcPushPopForm16<1, (outs), (ins rpt4imm:$cnt, popmreg:$rs),
+                                     "popm\t$cnt, $rs", []>;
+}
 } // Predicates = [HasMSP430X]
diff --git a/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt b/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
index 0ac8a359e23880..5acc0a8ed325d6 100644
--- a/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
+++ b/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
@@ -11,3 +11,7 @@
 0x5c 0x01
 0x43 0x18 0x0c 0x11
 0x5c 0x05
+
+# POPM with a range that would end above r15.
+# WARN: :[[@LINE+1]]:1: warning: invalid instruction encoding
+0xff 0x17
diff --git a/llvm/test/MC/Disassembler/MSP430/msp430x.txt b/llvm/test/MC/Disassembler/MSP430/msp430x.txt
index 0ee456ef92dd31..1af3b5a0285175 100644
--- a/llvm/test/MC/Disassembler/MSP430/msp430x.txt
+++ b/llvm/test/MC/Disassembler/MSP430/msp430x.txt
@@ -16,3 +16,9 @@
 0x40 0x18 0x49 0x59           # CHECK: addx.b r9, r9
 0x40 0x18 0x0c 0x55           # CHECK: addx r5, r12
 0x40 0x18 0x47 0x55           # CHECK: addx.b r5, r7
+0x04 0x15                     # CHECK: pushm #1, r4
+0x6a 0x15                     # CHECK: pushm #7, r10
+0xff 0x15                     # CHECK: pushm #16, r15
+0x04 0x17                     # CHECK: popm #1, r4
+0x64 0x17                     # CHECK: popm #7, r10
+0xf0 0x17                     # CHECK: popm #16, r15
diff --git a/llvm/test/MC/MSP430/msp430x-feature.s b/llvm/test/MC/MSP430/msp430x-feature.s
index 6d6ece721088e3..3f5305f182c85e 100644
--- a/llvm/test/MC/MSP430/msp430x-feature.s
+++ b/llvm/test/MC/MSP430/msp430x-feature.s
@@ -6,4 +6,8 @@
   rrax r12
 // CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
   rlax r12
+// CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  pushm #1, r4
+// CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  popm #1, r4
 // CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
diff --git a/llvm/test/MC/MSP430/pushm-popm-invalid.s b/llvm/test/MC/MSP430/pushm-popm-invalid.s
new file mode 100644
index 00000000000000..8bb90d6de4fc99
--- /dev/null
+++ b/llvm/test/MC/MSP430/pushm-popm-invalid.s
@@ -0,0 +1,37 @@
+// Test for errors when PUSHM/POPM instructions are misused.
+
+// RUN: not llvm-mc -triple msp430 -mcpu=msp430x < %s 2>&1 | FileCheck %s
+pushm:
+  pushm #0, r4
+  pushm #17, r4
+  pushm #17, r15
+  pushm r4
+  pushm #1, 0(r4)
+  pushm #1, &foo
+// CHECK: :9: error: invalid operand for instruction
+// CHECK: :9: error: invalid operand for instruction
+// CHECK: :9: error: invalid operand for instruction
+// CHECK: :9: error: invalid operand for instruction
+// CHECK: :13: error: invalid operand for instruction
+// CHECK: :13: error: invalid operand for instruction
+
+
+popm:
+  popm #0, r4
+  popm #17, r4
+  popm #17, r15
+  popm r4
+  popm #1, 0(r4)
+  popm #1, &foo
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :8: error: invalid operand for instruction
+// CHECK: :12: error: invalid operand for instruction
+// CHECK: :12: error: invalid operand for instruction
+
+// The register range must not extend below r0.
+  pushm #5, r3
+// CHECK: :[[@LINE-1]]:13: error: register range extends below r0
+  popm #16, r14
+// CHECK: :[[@LINE-1]]:13: error: register range extends below r0
diff --git a/llvm/test/MC/MSP430/pushm-popm.s b/llvm/test/MC/MSP430/pushm-popm.s
new file mode 100644
index 00000000000000..9814609886abda
--- /dev/null
+++ b/llvm/test/MC/MSP430/pushm-popm.s
@@ -0,0 +1,110 @@
+// Test the encoding of PUSHM/POPM instructions for the MSP430X CPU.
+
+// RUN: llvm-mc -triple msp430 -mcpu=msp430x -show-encoding < %s | FileCheck %s
+pushm:
+  pushm #1, r4
+  pushm #2, r5
+  pushm #3, r6
+  pushm #4, r7
+  pushm #5, r8
+  pushm #6, r9
+  pushm #7, r10
+  pushm #8, r11
+  pushm #9, r12
+  pushm #10, r13
+  pushm #11, r14
+  pushm #12, r15
+  pushm #16, r15
+
+  pushm #1, r15
+  pushm #2, r15
+  pushm #3, r15
+  pushm #4, r15
+  pushm #5, r15
+
+  pushm #1, r10
+  pushm #2, r10
+  pushm #3, r10
+  pushm #4, r10
+  pushm #5, r10
+
+// CHECK-LABEL: pushm:
+// CHECK-NEXT: pushm	#1, r4                          ; encoding: [0x04,0x15]
+// CHECK: pushm	#2, r5                          ; encoding: [0x15,0x15]
+// CHECK: pushm	#3, r6                          ; encoding: [0x26,0x15]
+// CHECK: pushm	#4, r7                          ; encoding: [0x37,0x15]
+// CHECK: pushm	#5, r8                          ; encoding: [0x48,0x15]
+// CHECK: pushm	#6, r9                          ; encoding: [0x59,0x15]
+// CHECK: pushm	#7, r10                         ; encoding: [0x6a,0x15]
+// CHECK: pushm	#8, r11                         ; encoding: [0x7b,0x15]
+// CHECK: pushm	#9, r12                         ; encoding: [0x8c,0x15]
+// CHECK: pushm	#10, r13                        ; encoding: [0x9d,0x15]
+// CHECK: pushm	#11, r14                        ; encoding: [0xae,0x15]
+// CHECK: pushm	#12, r15                        ; encoding: [0xbf,0x15]
+// CHECK: pushm	#16, r15                        ; encoding: [0xff,0x15]
+
+// CHECK: pushm	#1, r15                         ; encoding: [0x0f,0x15]
+// CHECK: pushm	#2, r15                         ; encoding: [0x1f,0x15]
+// CHECK: pushm	#3, r15                         ; encoding: [0x2f,0x15]
+// CHECK: pushm	#4, r15                         ; encoding: [0x3f,0x15]
+// CHECK: pushm	#5, r15                         ; encoding: [0x4f,0x15]
+
+// CHECK: pushm	#1, r10                         ; encoding: [0x0a,0x15]
+// CHECK: pushm	#2, r10                         ; encoding: [0x1a,0x15]
+// CHECK: pushm	#3, r10                         ; encoding: [0x2a,0x15]
+// CHECK: pushm	#4, r10                         ; encoding: [0x3a,0x15]
+// CHECK: pushm	#5, r10                         ; encoding: [0x4a,0x15]
+
+popm:
+  popm #1, r4
+  popm #2, r5
+  popm #3, r6
+  popm #4, r7
+  popm #5, r8
+  popm #6, r9
+  popm #7, r10
+  popm #8, r11
+  popm #9, r12
+  popm #10, r13
+  popm #11, r14
+  popm #12, r15
+  popm #16, r15
+
+  popm #1, r15
+  popm #2, r15
+  popm #3, r15
+  popm #4, r15
+  popm #5, r15
+
+  popm #1, r10
+  popm #2, r10
+  popm #3, r10
+  popm #4, r10
+  popm #5, r10
+
+// CHECK-LABEL: popm:
+// CHECK-NEXT: popm	#1, r4                          ; encoding: [0x04,0x17]
+// CHECK: popm	#2, r5                          ; encoding: [0x14,0x17]
+// CHECK: popm	#3, r6                          ; encoding: [0x24,0x17]
+// CHECK: popm	#4, r7                          ; encoding: [0x34,0x17]
+// CHECK: popm	#5, r8                          ; encoding: [0x44,0x17]
+// CHECK: popm	#6, r9                          ; encoding: [0x54,0x17]
+// CHECK: popm	#7, r10                         ; encoding: [0x64,0x17]
+// CHECK: popm	#8, r11                         ; encoding: [0x74,0x17]
+// CHECK: popm	#9, r12                         ; encoding: [0x84,0x17]
+// CHECK: popm	#10, r13                        ; encoding: [0x94,0x17]
+// CHECK: popm	#11, r14                        ; encoding: [0xa4,0x17]
+// CHECK: popm	#12, r15                        ; encoding: [0xb4,0x17]
+// CHECK: popm	#16, r15                        ; encoding: [0xf0,0x17]
+
+// CHECK: popm	#1, r15                         ; encoding: [0x0f,0x17]
+// CHECK: popm	#2, r15                         ; encoding: [0x1e,0x17]
+// CHECK: popm	#3, r15                         ; encoding: [0x2d,0x17]
+// CHECK: popm	#4, r15                         ; encoding: [0x3c,0x17]
+// CHECK: popm	#5, r15                         ; encoding: [0x4b,0x17]
+
+// CHECK: popm	#1, r10                         ; encoding: [0x0a,0x17]
+// CHECK: popm	#2, r10                         ; encoding: [0x19,0x17]
+// CHECK: popm	#3, r10                         ; encoding: [0x28,0x17]
+// CHECK: popm	#4, r10                         ; encoding: [0x37,0x17]
+// CHECK: popm	#5, r10                         ; encoding: [0x46,0x17]

>From a72f4b56187c5890630ea6a0b7394afa09e923b8 Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m at pm.me>
Date: Thu, 15 Oct 2026 11:56:06 +0200
Subject: [PATCH 6/6] [MSP430] support for movx.a

---
 .../MSP430/AsmParser/MSP430AsmParser.cpp      |  11 ++
 .../Disassembler/MSP430Disassembler.cpp       | 123 ++++++++++++------
 llvm/lib/Target/MSP430/MSP430InstrFormats.td  |  74 +++++++++--
 .../Target/MSP430/MSP430InstrInfoExtended.td  |  34 ++++-
 .../Disassembler/MSP430/msp430x-invalid.txt   |   9 ++
 llvm/test/MC/Disassembler/MSP430/msp430x.txt  |   5 +
 llvm/test/MC/MSP430/movx-invalid.s            |  24 ++++
 llvm/test/MC/MSP430/movx.s                    |  34 +++++
 llvm/test/MC/MSP430/msp430x-feature.s         |   2 +
 9 files changed, 261 insertions(+), 55 deletions(-)
 create mode 100644 llvm/test/MC/MSP430/movx-invalid.s
 create mode 100644 llvm/test/MC/MSP430/movx.s

diff --git a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
index 36c677ab9b3dc5..a643d529143836 100644
--- a/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
+++ b/llvm/lib/Target/MSP430/AsmParser/MSP430AsmParser.cpp
@@ -200,6 +200,17 @@ class MSP430Operand : public MCParsedAsmOperand {
     return false;
   }
 
+  /// Memory operand of an MSP430X instruction in non-register mode. The offset
+  /// must be a constant that fits in 20 bits.
+  bool isMem20() const {
+    if (!isMem())
+      return false;
+    if (!Mem.Offset)
+      return true;
+    const auto *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+    return CE && (isInt<20>(CE->getValue()) || isUInt<20>(CE->getValue()));
+  }
+
   StringRef getToken() const {
     assert(Kind == k_Tok && "Invalid access!");
     return Tok;
diff --git a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
index 4b50daed3631e6..c363df563dbb45 100644
--- a/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
+++ b/llvm/lib/Target/MSP430/Disassembler/MSP430Disassembler.cpp
@@ -146,6 +146,19 @@ static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits,
   return MCDisassembler::Success;
 }
 
+/// Like DecodeMemOperand, but bits 19:16 of the offset come from the extension
+/// word.
+static DecodeStatus decodeMem20Operand(MCInst &MI, uint64_t Bits,
+                                       uint64_t Address,
+                                       const MCDisassembler *Decoder) {
+  if (DecodeGR16RegisterClass(MI, Bits & 15, Address, Decoder) !=
+      MCDisassembler::Success)
+    return MCDisassembler::Fail;
+
+  MI.addOperand(MCOperand::createImm(SignExtend64<20>(Bits >> 4)));
+  return MCDisassembler::Success;
+}
+
 /// POPM encodes Rdst - n + 1 for Rdst, while PUSHM encodes Rdst. The count n
 /// is decoded before the register.
 static DecodeStatus decodePOPMRegOperand(MCInst &MI, uint64_t Bits,
@@ -222,6 +235,31 @@ static AddrMode DecodeDstAddrMode(unsigned Insn) {
   return Ad ? amIndexed : amRegister;
 }
 
+/// Number of operand words that follow a Format I instruction word.
+static unsigned getOperandWordsI(AddrMode SrcAM, AddrMode DstAM) {
+  unsigned Words = 0;
+  switch (SrcAM) {
+  case amIndexed:
+  case amSymbolic:
+  case amImmediate:
+  case amAbsolute:
+    ++Words;
+    break;
+  default:
+    break;
+  }
+  switch (DstAM) {
+  case amIndexed:
+  case amSymbolic:
+  case amAbsolute:
+    ++Words;
+    break;
+  default:
+    break;
+  }
+  return Words;
+}
+
 static const uint8_t *getDecoderTable(AddrMode SrcAM, unsigned Words) {
   assert(0 < Words && Words < 4 && "Incorrect number of words");
   switch (SrcAM) {
@@ -258,37 +296,14 @@ DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size,
     return MCDisassembler::Fail;
   }
 
-  unsigned Words = 1;
-  switch (SrcAM) {
-  case amIndexed:
-  case amSymbolic:
-  case amImmediate:
-  case amAbsolute:
-    if (Bytes.size() < (Words + 1) * 2) {
-      Size = 2;
-      return DecodeStatus::Fail;
-    }
-    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
-    ++Words;
-    break;
-  default:
-    break;
-  }
-  switch (DstAM) {
-  case amIndexed:
-  case amSymbolic:
-  case amAbsolute:
-    if (Bytes.size() < (Words + 1) * 2) {
-      Size = 2;
-      return DecodeStatus::Fail;
-    }
-    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + Words * 2)
-        << (Words * 16);
-    ++Words;
-    break;
-  default:
-    break;
+  unsigned Words = 1 + getOperandWordsI(SrcAM, DstAM);
+  if (Bytes.size() < Words * 2) {
+    Size = 2;
+    return DecodeStatus::Fail;
   }
+  for (unsigned I = 1; I < Words; ++I)
+    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + I * 2)
+            << (I * 16);
 
   DecodeStatus Result = decodeInstruction(getDecoderTable(SrcAM, Words), MI,
                                           Insn, Address, this, STI);
@@ -390,20 +405,47 @@ DecodeStatus MSP430Disassembler::getInstructionX(MCInst &MI, uint64_t &Size,
       Size = 2;
       return DecodeStatus::Fail;
     }
-    Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
+    uint64_t InsnWord = support::endian::read16le(Bytes.data() + 2);
     Words = 2;
+    // A Format I word can have operand words. Format II words behind an
+    // extension word are only supported in register mode so far.
+    if (InsnWord >= 0x4000)
+      Words += getOperandWordsI(DecodeSrcAddrModeI(InsnWord),
+                                DecodeDstAddrMode(InsnWord));
+    if (Bytes.size() < Words * 2) {
+      Size = 4;
+      return DecodeStatus::Fail;
+    }
+    for (unsigned I = 1; I < Words; ++I)
+      Insn |= (uint64_t)support::endian::read16le(Bytes.data() + I * 2)
+              << (I * 16);
   }
 
-  // MSP430X32 decodes the extension word together with the following Format I
-  // or II word. Each combination is its own instruction, like RRCX_16 or
-  // ADDX16rr, so the plain Format I and II tables are not used here.
-  const uint8_t *DecoderTable =
-      Words == 2 ? DecoderTableMSP430X32 : DecoderTableMSP430X16;
+  // MSP430X32 and MSP430X48 decode the extension word together with the
+  // following Format I or II word and its operand words. Each combination is
+  // its own instruction, like RRCX_16 or MOVXAmn, so the plain Format I and II
+  // tables are not used here.
+  const uint8_t *DecoderTable;
+  switch (Words) {
+  case 1:
+    DecoderTable = DecoderTableMSP430X16;
+    break;
+  case 2:
+    DecoderTable = DecoderTableMSP430X32;
+    break;
+  case 3:
+    DecoderTable = DecoderTableMSP430X48;
+    break;
+  default:
+    // Two operand words are not supported yet.
+    Size = Words * 2;
+    return DecodeStatus::Fail;
+  }
   DecodeStatus Result =
       decodeInstruction(DecoderTable, MI, Insn, Address, this, STI);
   // The word after an extension word is a valid Format I or II instruction on
-  // its own. Skip it on failure too, so it is not shown without the extension
-  // word.
+  // its own. Skip it and its operand words on failure too, so they are not
+  // shown without the extension word.
   Size = Words * 2;
   return Result;
 }
@@ -425,11 +467,12 @@ DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
   //   0x0000-0x0fff  X        addr, II*  MOVA, ADDA, ..., RRCM, RRAM, RLAM, ...
   //   0x1000-0x13ff  II       II         RRC, SWPB, RRA, SXT, PUSH, CALL, RETI
   //   0x1400-0x17ff  X        II*        PUSHM, POPM
-  //   0x1800-0x1fff  X        ext+I/II   RRCX, RRAX, ADDX, ...
+  //   0x1800-0x1fff  X        ext+I/II   RRCX, ADDX, MOVX, ...
   //   0x2000-0x3fff  CJ       jump       JMP, JNE, ...
   //   0x4000-0xffff  I        I          MOV, ADD, ...
   //
-  // ext+I/II is an extension word followed by a Format I or II word.
+  // ext+I/II is an extension word followed by a Format I or II word and its
+  // operand words.
   uint64_t Insn = support::endian::read16le(Bytes.data());
   unsigned FormatBits = fieldFromInstruction(Insn, 13, 3);
   switch (FormatBits) {
diff --git a/llvm/lib/Target/MSP430/MSP430InstrFormats.td b/llvm/lib/Target/MSP430/MSP430InstrFormats.td
index 384315b030b95b..4a70ed379a0754 100644
--- a/llvm/lib/Target/MSP430/MSP430InstrFormats.td
+++ b/llvm/lib/Target/MSP430/MSP430InstrFormats.td
@@ -463,29 +463,46 @@ class IIExtExcRotForm16<bits<2> opcode,
                         dag outs, dag ins, string asmstr, list<dag> pattern>
   : IIExtExcRotForm<opcode, ALWord, outs, ins, asmstr, pattern>;
 
-// MSP430X extended instructions in register mode.
+// MSP430X extended instructions.
 //
 // The extension word precedes the instruction word in memory, so it occupies
-// Inst{15-0} and the instruction word is in Inst{31-16}.
-//
-// FIXME: Add the non-register mode, which is needed for 20-bit memory
-// operands.
-class ExtRegForm<bit zc, bit rpt, ALKind al,
-                 dag outs, dag ins, string asmstr, list<dag> pattern>
-  : MSP430Inst<outs, ins, 4, asmstr> {
+// Inst{15-0} and the instruction word is in Inst{31-16}. Operand words follow
+// from Inst{47-32}.
+class ExtWordForm<ALKind al, int size,
+                  dag outs, dag ins, string asmstr, list<dag> pattern>
+  : MSP430Inst<outs, ins, size, asmstr> {
   let Pattern = pattern;
   let DecoderNamespace = "MSP430X";
 
+  let Inst{15-11} = 0b00011;
+  let Inst{6}     = al.Value;
+  let Inst{5-4}   = 0b00;
+}
+
+// Register mode. The extension word holds the repeat count.
+class ExtRegForm<bit zc, bit rpt, ALKind al,
+                 dag outs, dag ins, string asmstr, list<dag> pattern>
+  : ExtWordForm<al, 4, outs, ins, asmstr, pattern> {
   bits<4> cnt = 0;
 
-  let Inst{15-9} = 0b0001100;
+  let Inst{10-9} = 0b00;
   let Inst{8}    = zc;
   let Inst{7}    = rpt;
-  let Inst{6}    = al.Value;
-  let Inst{5-4}  = 0b00;
   let Inst{3-0}  = cnt;
 }
 
+// Non-register mode. The extension word holds bits 19:16 of the source and
+// destination operand words.
+class ExtMemForm<ALKind al, int size,
+                 dag outs, dag ins, string asmstr, list<dag> pattern>
+  : ExtWordForm<al, size, outs, ins, asmstr, pattern> {
+  bits<4> srchi = 0;
+  bits<4> dsthi = 0;
+
+  let Inst{10-7} = srchi;
+  let Inst{3-0}  = dsthi;
+}
+
 // Same layout as IIForm, moved behind the extension word.
 class IIExtRegForm<bits<3> opcode, bit bw, bit zc, bit rpt,
                    dag outs, dag ins, string asmstr, list<dag> pattern>
@@ -527,6 +544,41 @@ class I16rExtended<bits<4> opcode, bit zc, bit rpt,
                    dag outs, dag ins, string asmstr, list<dag> pattern>
   : IExtRegForm<opcode, 0, zc, rpt, outs, ins, asmstr, pattern>;
 
+// Same layout as IForm, moved behind the extension word in non-register mode.
+class IExtMemForm<bits<4> opcode, ALKind al, bit bw, DestMode ad,
+                  SourceMode as, int size,
+                  dag outs, dag ins, string asmstr, list<dag> pattern>
+  : ExtMemForm<al, size, outs, ins, asmstr, pattern> {
+  bits<4> rs;
+  bits<4> rd;
+
+  let Inst{31-28} = opcode;
+  let Inst{27-24} = rs;
+  let Inst{23}    = ad.Value;
+  let Inst{22}    = bw;
+  let Inst{21-20} = as.Value;
+  let Inst{19-16} = rd;
+}
+
+// Indexed or absolute destination with a 20-bit offset, indirect source.
+class IExtMemFormMN<bits<4> opcode, ALKind al, bit bw,
+                    dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IExtMemForm<opcode, al, bw, DstMem, SrcIndReg, 6,
+                outs, ins, asmstr, pattern> {
+  bits<24> dst;
+  let rd = dst{3-0};
+  let Inst{47-32} = dst{19-4};
+  let dsthi = dst{23-20};
+}
+
+// .A uses A/L = 0 with B/W = 1, .W uses A/L = 1 with B/W = 0.
+class IAmnExtended<bits<4> opcode,
+                   dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IExtMemFormMN<opcode, ALAddr, 1, outs, ins, asmstr, pattern>;
+class I16mnExtended<bits<4> opcode,
+                    dag outs, dag ins, string asmstr, list<dag> pattern>
+  : IExtMemFormMN<opcode, ALWord, 0, outs, ins, asmstr, pattern>;
+
 // PUSHM and POPM. Single-word MSP430X instructions with their own layout in
 // the Format II opcode space, without an extension word. TI calls them Format
 // II exceptions.
diff --git a/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td b/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
index d078531f7f0ffc..891c237890e75d 100644
--- a/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
+++ b/llvm/lib/Target/MSP430/MSP430InstrInfoExtended.td
@@ -11,12 +11,13 @@
 //===----------------------------------------------------------------------===//
 
 // TODO: Most extended instructions have a .A version that enables 20-bit
-// operands. This requires support the large memory model to be implemented.
+// operands. This requires support for the large memory model.
 //
 // Only the extended instructions that are useful in the small memory model
-// (16-bit pointers) are implemented so far. Instructions like MOVX are not
-// required in the small memory model, and have increased size/cycle count
-// compared to their 430 versions.
+// (16-bit pointers) are implemented so far. Most MOVX forms are not needed
+// there and are larger and slower than MOV. MOVX.A @Rs, x(Rd) is the
+// exception, because 20-bit registers like the DMA address registers can only
+// be written with a single 20-bit store.
 
 //===----------------------------------------------------------------------===//
 //  Operands
@@ -51,6 +52,21 @@ def popmreg : RegisterOperand<GR16> {
   let DecoderMethod = "decodePOPMRegOperand";
 }
 
+// Memory operand with a 20-bit offset. Bits 19:16 go into the extension word.
+// Only constant offsets are accepted, because there are no 20-bit fixups yet.
+def Mem20AsmOperand : AsmOperandClass {
+  let Name = "Mem20";
+  let RenderMethod = "addMemOperands";
+}
+
+def memdst20 : Operand<i32> {
+  let PrintMethod = "printSrcMemOperand";
+  let MIOperandInfo = (ops GR16, i32imm);
+  let ParserMatchClass = Mem20AsmOperand;
+  let EncoderMethod = "getMemOpValue";
+  let DecoderMethod = "decodeMem20Operand";
+}
+
 //===----------------------------------------------------------------------===//
 //  Shift Instructions
 //
@@ -103,6 +119,16 @@ let Defs = [SR], Constraints = "$src2 = $rd" in {
 def RLAX8r  : InstAlias<"rlax.b\t$dst", (ADDX8rr  GR8:$dst,  GR8:$dst),  0>;
 def RLAX16r : InstAlias<"rlax\t$dst",   (ADDX16rr GR16:$dst, GR16:$dst), 0>;
 
+//===----------------------------------------------------------------------===//
+//  Move Instructions
+//
+let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in {
+def MOVXAmn  : IAmnExtended<0b0100, (outs), (ins memdst20:$dst, indreg:$rs),
+                            "movx.a\t$rs, $dst", []>;
+def MOVX16mn : I16mnExtended<0b0100, (outs), (ins memdst20:$dst, indreg:$rs),
+                             "movx\t$rs, $dst", []>;
+}
+
 //===----------------------------------------------------------------------===//
 //  Push/Pop Multiple Registers
 //
diff --git a/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt b/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
index 5acc0a8ed325d6..9bd0b6390b719b 100644
--- a/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
+++ b/llvm/test/MC/Disassembler/MSP430/msp430x-invalid.txt
@@ -15,3 +15,12 @@
 # POPM with a range that would end above r15.
 # WARN: :[[@LINE+1]]:1: warning: invalid instruction encoding
 0xff 0x17
+
+# An unsupported extended instruction with two operand words
+# (movx 2(r13), 4(r12)) is skipped as a whole, including its operand words.
+# CHECK: rram #1, r12
+# CHECK-NEXT: rram #2, r12
+# WARN: :[[@LINE+2]]:1: warning: invalid instruction encoding
+0x5c 0x01
+0x40 0x18 0x9c 0x4d 0x02 0x00 0x04 0x00
+0x5c 0x05
diff --git a/llvm/test/MC/Disassembler/MSP430/msp430x.txt b/llvm/test/MC/Disassembler/MSP430/msp430x.txt
index 1af3b5a0285175..c361c5df97cccd 100644
--- a/llvm/test/MC/Disassembler/MSP430/msp430x.txt
+++ b/llvm/test/MC/Disassembler/MSP430/msp430x.txt
@@ -22,3 +22,8 @@
 0x04 0x17                     # CHECK: popm #1, r4
 0x64 0x17                     # CHECK: popm #7, r10
 0xf0 0x17                     # CHECK: popm #16, r15
+0x00 0x18 0xec 0x4d 0x00 0x00 # CHECK: movx.a @r13, 0(r12)
+0x01 0x18 0xec 0x4d 0x45 0x23 # CHECK: movx.a @r13, 74565(r12)
+0x0f 0x18 0xec 0x4d 0xfe 0xff # CHECK: movx.a @r13, -2(r12)
+0x01 0x18 0xe2 0x44 0x12 0x05 # CHECK: movx.a @r4, &66834
+0x40 0x18 0xac 0x4d 0x02 0x00 # CHECK: movx @r13, 2(r12)
diff --git a/llvm/test/MC/MSP430/movx-invalid.s b/llvm/test/MC/MSP430/movx-invalid.s
new file mode 100644
index 00000000000000..c9ff31a9885f11
--- /dev/null
+++ b/llvm/test/MC/MSP430/movx-invalid.s
@@ -0,0 +1,24 @@
+// Test for errors when MOVX instructions are misused.
+
+// RUN: not llvm-mc -triple msp430 -mcpu=msp430x < %s 2>&1 | FileCheck %s
+
+// The offset must fit in 20 bits.
+  movx.a @r13, 0x100000(r12)
+// CHECK: :[[@LINE-1]]:16: error: invalid operand for instruction
+  movx.a @r13, -0x80001(r12)
+// CHECK: :[[@LINE-1]]:16: error: invalid operand for instruction
+
+// Symbolic offsets need 20-bit fixups, which are not supported yet.
+  movx.a @r13, foo(r12)
+// CHECK: :[[@LINE-1]]:16: error: invalid operand for instruction
+  movx.a @r13, &foo
+// CHECK: :[[@LINE-1]]:16: error: invalid operand for instruction
+
+// Only an indirect source and an indexed or absolute destination are
+// supported so far.
+  movx.a r13, 0(r12)
+// CHECK: :[[@LINE-1]]:10: error: invalid operand for instruction
+  movx.a @r13+, 0(r12)
+// CHECK: :[[@LINE-1]]:10: error: invalid operand for instruction
+  movx.a @r13, r12
+// CHECK: :[[@LINE-1]]:16: error: invalid operand for instruction
diff --git a/llvm/test/MC/MSP430/movx.s b/llvm/test/MC/MSP430/movx.s
new file mode 100644
index 00000000000000..ec66fb69c79db5
--- /dev/null
+++ b/llvm/test/MC/MSP430/movx.s
@@ -0,0 +1,34 @@
+// Test the encoding of MOVX instructions for the MSP430X CPU.
+
+// RUN: llvm-mc -triple msp430 -mcpu=msp430x -show-encoding < %s | FileCheck %s
+movx_a:
+  movx.a @r13, 0(r12)
+  movx.a @r13, 2(r12)
+  movx.a @r13, 0x12345(r12)
+  movx.a @r13, 0xfffff(r12)
+  movx.a @r13, -2(r12)
+  movx.a @r13, -0x80000(r12)
+  movx.a @r4, &0x0512
+  movx.a @r4, &0x10512
+
+// CHECK-LABEL: movx_a:
+// CHECK-NEXT: movx.a	@r13, 0(r12)                    ; encoding: [0x00,0x18,0xec,0x4d,0x00,0x00]
+// CHECK-NEXT: movx.a	@r13, 2(r12)                    ; encoding: [0x00,0x18,0xec,0x4d,0x02,0x00]
+// CHECK-NEXT: movx.a	@r13, 74565(r12)                ; encoding: [0x01,0x18,0xec,0x4d,0x45,0x23]
+// CHECK-NEXT: movx.a	@r13, 1048575(r12)              ; encoding: [0x0f,0x18,0xec,0x4d,0xff,0xff]
+// CHECK-NEXT: movx.a	@r13, -2(r12)                   ; encoding: [0x0f,0x18,0xec,0x4d,0xfe,0xff]
+// CHECK-NEXT: movx.a	@r13, -524288(r12)              ; encoding: [0x08,0x18,0xec,0x4d,0x00,0x00]
+// CHECK-NEXT: movx.a	@r4, &1298                      ; encoding: [0x00,0x18,0xe2,0x44,0x12,0x05]
+// CHECK-NEXT: movx.a	@r4, &66834                     ; encoding: [0x01,0x18,0xe2,0x44,0x12,0x05]
+
+movx_w:
+  movx @r13, 0(r12)
+  movx.w @r13, 0(r12)
+  movx @r13, 0x12345(r12)
+  movx @r4, &0x0512
+
+// CHECK-LABEL: movx_w:
+// CHECK-NEXT: movx	@r13, 0(r12)                    ; encoding: [0x40,0x18,0xac,0x4d,0x00,0x00]
+// CHECK-NEXT: movx	@r13, 0(r12)                    ; encoding: [0x40,0x18,0xac,0x4d,0x00,0x00]
+// CHECK-NEXT: movx	@r13, 74565(r12)                ; encoding: [0x41,0x18,0xac,0x4d,0x45,0x23]
+// CHECK-NEXT: movx	@r4, &1298                      ; encoding: [0x40,0x18,0xa2,0x44,0x12,0x05]
diff --git a/llvm/test/MC/MSP430/msp430x-feature.s b/llvm/test/MC/MSP430/msp430x-feature.s
index 3f5305f182c85e..8ed9c1e3eb6f34 100644
--- a/llvm/test/MC/MSP430/msp430x-feature.s
+++ b/llvm/test/MC/MSP430/msp430x-feature.s
@@ -10,4 +10,6 @@
   pushm #1, r4
 // CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
   popm #1, r4
+// CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movx.a @r13, 0(r12)
 // CHECK: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled



More information about the cfe-commits mailing list