llvm.org GIT mirror llvm / 5fedd08
[MSP430] Add MC layer Summary: This change implements assembler parser, code emitter, ELF object writer and disassembler for the MSP430 ISA. Also, more instruction forms are added to the target description. Reviewers: asl Reviewed By: asl Subscribers: pftbest, krisb, mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D53661 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346374 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 10 months ago
73 changed file(s) with 3383 addition(s) and 1364 deletion(s). Raw diff Collapse all Expand all
728728 #include "ELFRelocs/BPF.def"
729729 };
730730
731 // MSP430 specific e_flags
732 enum : unsigned {
733 EF_MSP430_MACH_MSP430x11 = 11,
734 EF_MSP430_MACH_MSP430x11x1 = 110,
735 EF_MSP430_MACH_MSP430x12 = 12,
736 EF_MSP430_MACH_MSP430x13 = 13,
737 EF_MSP430_MACH_MSP430x14 = 14,
738 EF_MSP430_MACH_MSP430x15 = 15,
739 EF_MSP430_MACH_MSP430x16 = 16,
740 EF_MSP430_MACH_MSP430x20 = 20,
741 EF_MSP430_MACH_MSP430x22 = 22,
742 EF_MSP430_MACH_MSP430x23 = 23,
743 EF_MSP430_MACH_MSP430x24 = 24,
744 EF_MSP430_MACH_MSP430x26 = 26,
745 EF_MSP430_MACH_MSP430x31 = 31,
746 EF_MSP430_MACH_MSP430x32 = 32,
747 EF_MSP430_MACH_MSP430x33 = 33,
748 EF_MSP430_MACH_MSP430x41 = 41,
749 EF_MSP430_MACH_MSP430x42 = 42,
750 EF_MSP430_MACH_MSP430x43 = 43,
751 EF_MSP430_MACH_MSP430x44 = 44,
752 EF_MSP430_MACH_MSP430X = 45,
753 EF_MSP430_MACH_MSP430x46 = 46,
754 EF_MSP430_MACH_MSP430x47 = 47,
755 EF_MSP430_MACH_MSP430x54 = 54,
756 };
757
758 // ELF Relocation types for MSP430
759 enum {
760 #include "ELFRelocs/MSP430.def"
761 };
762
731763 #undef ELF_RELOC
732764
733765 // Section header.
832864 SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section.
833865 SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
834866
867 SHT_MSP430_ATTRIBUTES = 0x70000003U,
868
835869 SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
836870 SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
837871 SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
0
1 #ifndef ELF_RELOC
2 #error "ELF_RELOC must be defined"
3 #endif
4
5 ELF_RELOC(R_MSP430_NONE, 0)
6 ELF_RELOC(R_MSP430_32, 1)
7 ELF_RELOC(R_MSP430_10_PCREL, 2)
8 ELF_RELOC(R_MSP430_16, 3)
9 ELF_RELOC(R_MSP430_16_PCREL, 4)
10 ELF_RELOC(R_MSP430_16_BYTE, 5)
11 ELF_RELOC(R_MSP430_16_PCREL_BYTE, 6)
12 ELF_RELOC(R_MSP430_2X_PCREL, 7)
13 ELF_RELOC(R_MSP430_RL_PCREL, 8)
14 ELF_RELOC(R_MSP430_8, 9)
15 ELF_RELOC(R_MSP430_SYM_DIFF, 10)
10201020 return "ELF32-lanai";
10211021 case ELF::EM_MIPS:
10221022 return "ELF32-mips";
1023 case ELF::EM_MSP430:
1024 return "ELF32-msp430";
10231025 case ELF::EM_PPC:
10241026 return "ELF32-ppc";
10251027 case ELF::EM_RISCV:
10901092 default:
10911093 report_fatal_error("Invalid ELFCLASS!");
10921094 }
1095 case ELF::EM_MSP430:
1096 return Triple::msp430;
10931097 case ELF::EM_PPC:
10941098 return Triple::ppc;
10951099 case ELF::EM_PPC64:
5151 textual header "BinaryFormat/ELFRelocs/i386.def"
5252 textual header "BinaryFormat/ELFRelocs/Lanai.def"
5353 textual header "BinaryFormat/ELFRelocs/Mips.def"
54 textual header "BinaryFormat/ELFRelocs/MSP430.def"
5455 textual header "BinaryFormat/ELFRelocs/PowerPC64.def"
5556 textual header "BinaryFormat/ELFRelocs/PowerPC.def"
5657 textual header "BinaryFormat/ELFRelocs/RISCV.def"
134134 case ELF::EM_BPF:
135135 switch (Type) {
136136 #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
137 default:
138 break;
139 }
140 break;
141 case ELF::EM_MSP430:
142 switch (Type) {
143 #include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
137144 default:
138145 break;
139146 }
0 add_llvm_library(LLVMMSP430AsmParser
1 MSP430AsmParser.cpp
2 )
0 ;===- lib/Target/MSP430/AsmParser/LLVMBuild.txt ----------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = MSP430AsmParser
20 parent = MSP430
21 required_libraries = MC MCParser MSP430Desc MSP430Info Support
22 add_to_library_groups = MSP430
0 //===- MSP430AsmParser.cpp - Parse MSP430 assembly to MCInst instructions -===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "MSP430.h"
10 #include "MSP430RegisterInfo.h"
11 #include "MCTargetDesc/MSP430MCTargetDesc.h"
12
13 #include "llvm/ADT/APInt.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstBuilder.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
21 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCValue.h"
26 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/MathExtras.h"
28 #include "llvm/Support/TargetRegistry.h"
29
30 #define DEBUG_TYPE "msp430-asm-parser"
31
32 namespace llvm {
33
34 /// Parses MSP430 assembly from a stream.
35 class MSP430AsmParser : public MCTargetAsmParser {
36 const MCSubtargetInfo &STI;
37 MCAsmParser &Parser;
38 const MCRegisterInfo *MRI;
39
40 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
41 OperandVector &Operands, MCStreamer &Out,
42 uint64_t &ErrorInfo,
43 bool MatchingInlineAsm) override;
44
45 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
46
47 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
48 SMLoc NameLoc, OperandVector &Operands) override;
49
50 bool ParseDirective(AsmToken DirectiveID) override;
51
52 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
53 unsigned Kind) override;
54
55 bool parseJccInstruction(ParseInstructionInfo &Info, StringRef Name,
56 SMLoc NameLoc, OperandVector &Operands);
57
58 bool ParseOperand(OperandVector &Operands);
59
60 bool ParseLiteralValues(unsigned Size, SMLoc L);
61
62 MCAsmParser &getParser() const { return Parser; }
63 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
64
65 /// @name Auto-generated Matcher Functions
66 /// {
67
68 #define GET_ASSEMBLER_HEADER
69 #include "MSP430GenAsmMatcher.inc"
70
71 /// }
72
73 public:
74 MSP430AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
75 const MCInstrInfo &MII, const MCTargetOptions &Options)
76 : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) {
77 MCAsmParserExtension::Initialize(Parser);
78 MRI = getContext().getRegisterInfo();
79
80 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
81 }
82 };
83
84 /// A parsed MSP430 assembly operand.
85 class MSP430Operand : public MCParsedAsmOperand {
86 typedef MCParsedAsmOperand Base;
87
88 enum KindTy {
89 k_Imm,
90 k_Reg,
91 k_Tok,
92 k_Mem,
93 k_IndReg,
94 k_PostIndReg
95 } Kind;
96
97 struct Memory {
98 unsigned Reg;
99 const MCExpr *Offset;
100 };
101 union {
102 const MCExpr *Imm;
103 unsigned Reg;
104 StringRef Tok;
105 Memory Mem;
106 };
107
108 SMLoc Start, End;
109
110 public:
111 MSP430Operand(StringRef Tok, SMLoc const &S)
112 : Base(), Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
113 MSP430Operand(KindTy Kind, unsigned Reg, SMLoc const &S, SMLoc const &E)
114 : Base(), Kind(Kind), Reg(Reg), Start(S), End(E) {}
115 MSP430Operand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
116 : Base(), Kind(k_Imm), Imm(Imm), Start(S), End(E) {}
117 MSP430Operand(unsigned Reg, MCExpr const *Expr, SMLoc const &S, SMLoc const &E)
118 : Base(), Kind(k_Mem), Mem({Reg, Expr}), Start(S), End(E) {}
119
120 void addRegOperands(MCInst &Inst, unsigned N) const {
121 assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&
122 "Unexpected operand kind");
123 assert(N == 1 && "Invalid number of operands!");
124
125 Inst.addOperand(MCOperand::createReg(Reg));
126 }
127
128 void addExprOperand(MCInst &Inst, const MCExpr *Expr) const {
129 // Add as immediate when possible
130 if (!Expr)
131 Inst.addOperand(MCOperand::createImm(0));
132 else if (const MCConstantExpr *CE = dyn_cast(Expr))
133 Inst.addOperand(MCOperand::createImm(CE->getValue()));
134 else
135 Inst.addOperand(MCOperand::createExpr(Expr));
136 }
137
138 void addImmOperands(MCInst &Inst, unsigned N) const {
139 assert(Kind == k_Imm && "Unexpected operand kind");
140 assert(N == 1 && "Invalid number of operands!");
141
142 addExprOperand(Inst, Imm);
143 }
144
145 void addMemOperands(MCInst &Inst, unsigned N) const {
146 assert(Kind == k_Mem && "Unexpected operand kind");
147 assert(N == 2 && "Invalid number of operands");
148
149 Inst.addOperand(MCOperand::createReg(Mem.Reg));
150 addExprOperand(Inst, Mem.Offset);
151 }
152
153 bool isReg() const { return Kind == k_Reg; }
154 bool isImm() const { return Kind == k_Imm; }
155 bool isToken() const { return Kind == k_Tok; }
156 bool isMem() const { return Kind == k_Mem; }
157 bool isIndReg() const { return Kind == k_IndReg; }
158 bool isPostIndReg() const { return Kind == k_PostIndReg; }
159
160 bool isCGImm() const {
161 if (Kind != k_Imm)
162 return false;
163
164 int64_t Val;
165 if (!Imm->evaluateAsAbsolute(Val))
166 return false;
167
168 if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
169 return true;
170
171 return false;
172 }
173
174 StringRef getToken() const {
175 assert(Kind == k_Tok && "Invalid access!");
176 return Tok;
177 }
178
179 unsigned getReg() const {
180 assert(Kind == k_Reg && "Invalid access!");
181 return Reg;
182 }
183
184 void setReg(unsigned RegNo) {
185 assert(Kind == k_Reg && "Invalid access!");
186 Reg = RegNo;
187 }
188
189 static std::unique_ptr CreateToken(StringRef Str, SMLoc S) {
190 return make_unique(Str, S);
191 }
192
193 static std::unique_ptr CreateReg(unsigned RegNum, SMLoc S,
194 SMLoc E) {
195 return make_unique(k_Reg, RegNum, S, E);
196 }
197
198 static std::unique_ptr CreateImm(const MCExpr *Val, SMLoc S,
199 SMLoc E) {
200 return make_unique(Val, S, E);
201 }
202
203 static std::unique_ptr CreateMem(unsigned RegNum,
204 const MCExpr *Val,
205 SMLoc S, SMLoc E) {
206 return make_unique(RegNum, Val, S, E);
207 }
208
209 static std::unique_ptr CreateIndReg(unsigned RegNum, SMLoc S,
210 SMLoc E) {
211 return make_unique(k_IndReg, RegNum, S, E);
212 }
213
214 static std::unique_ptr CreatePostIndReg(unsigned RegNum, SMLoc S,
215 SMLoc E) {
216 return make_unique(k_PostIndReg, RegNum, S, E);
217 }
218
219 SMLoc getStartLoc() const { return Start; }
220 SMLoc getEndLoc() const { return End; }
221
222 virtual void print(raw_ostream &O) const {
223 switch (Kind) {
224 case k_Tok:
225 O << "Token " << Tok;
226 break;
227 case k_Reg:
228 O << "Register " << Reg;
229 break;
230 case k_Imm:
231 O << "Immediate " << *Imm;
232 break;
233 case k_Mem:
234 O << "Memory ";
235 O << *Mem.Offset << "(" << Reg << ")";
236 break;
237 case k_IndReg:
238 O << "RegInd " << Reg;
239 break;
240 case k_PostIndReg:
241 O << "PostInc " << Reg;
242 break;
243 }
244 }
245 };
246
247 bool MSP430AsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
248 OperandVector &Operands,
249 MCStreamer &Out,
250 uint64_t &ErrorInfo,
251 bool MatchingInlineAsm) {
252 MCInst Inst;
253 unsigned MatchResult =
254 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
255
256 switch (MatchResult) {
257 case Match_Success:
258 Inst.setLoc(Loc);
259 Out.EmitInstruction(Inst, STI);
260 return false;
261 case Match_MnemonicFail:
262 return Error(Loc, "invalid instruction mnemonic");
263 case Match_InvalidOperand: {
264 SMLoc ErrorLoc = Loc;
265 if (ErrorInfo != ~0U) {
266 if (ErrorInfo >= Operands.size())
267 return Error(ErrorLoc, "too few operands for instruction");
268
269 ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc();
270 if (ErrorLoc == SMLoc())
271 ErrorLoc = Loc;
272 }
273 return Error(ErrorLoc, "invalid operand for instruction");
274 }
275 default:
276 return true;
277 }
278 }
279
280 // Auto-generated by TableGen
281 static unsigned MatchRegisterName(StringRef Name);
282 static unsigned MatchRegisterAltName(StringRef Name);
283
284 bool MSP430AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
285 SMLoc &EndLoc) {
286 if (getLexer().getKind() == AsmToken::Identifier) {
287 auto Name = getLexer().getTok().getIdentifier().lower();
288 RegNo = MatchRegisterName(Name);
289 if (RegNo == MSP430::NoRegister) {
290 RegNo = MatchRegisterAltName(Name);
291 if (RegNo == MSP430::NoRegister)
292 return true;
293 }
294
295 AsmToken const &T = getParser().getTok();
296 StartLoc = T.getLoc();
297 EndLoc = T.getEndLoc();
298 getLexer().Lex(); // eat register token
299
300 return false;
301 }
302
303 return Error(StartLoc, "invalid register name");
304 }
305
306 bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info,
307 StringRef Name, SMLoc NameLoc,
308 OperandVector &Operands) {
309 if (!Name.startswith_lower("j"))
310 return true;
311
312 auto CC = Name.drop_front().lower();
313 unsigned CondCode;
314 if (CC == "ne" || CC == "nz")
315 CondCode = MSP430CC::COND_NE;
316 else if (CC == "eq" || CC == "z")
317 CondCode = MSP430CC::COND_E;
318 else if (CC == "lo" || CC == "nc")
319 CondCode = MSP430CC::COND_LO;
320 else if (CC == "hs" || CC == "c")
321 CondCode = MSP430CC::COND_HS;
322 else if (CC == "n")
323 CondCode = MSP430CC::COND_N;
324 else if (CC == "ge")
325 CondCode = MSP430CC::COND_GE;
326 else if (CC == "l")
327 CondCode = MSP430CC::COND_L;
328 else if (CC == "mp")
329 CondCode = MSP430CC::COND_NONE;
330 else
331 return Error(NameLoc, "unknown instruction");
332
333 if (CondCode == (unsigned)MSP430CC::COND_NONE)
334 Operands.push_back(MSP430Operand::CreateToken("jmp", NameLoc));
335 else {
336 Operands.push_back(MSP430Operand::CreateToken("j", NameLoc));
337 const MCExpr *CCode = MCConstantExpr::create(CondCode, getContext());
338 Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));
339 }
340
341 // Skip optional '$' sign.
342 if (getLexer().getKind() == AsmToken::Dollar)
343 getLexer().Lex(); // Eat '$'
344
345 const MCExpr *Val;
346 SMLoc ExprLoc = getLexer().getLoc();
347 if (getParser().parseExpression(Val))
348 return Error(ExprLoc, "expected expression operand");
349
350 int64_t Res;
351 if (Val->evaluateAsAbsolute(Res))
352 if (Res < -512 || Res > 511)
353 return Error(ExprLoc, "invalid jump offset");
354
355 Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,
356 getLexer().getLoc()));
357
358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
359 SMLoc Loc = getLexer().getLoc();
360 getParser().eatToEndOfStatement();
361 return Error(Loc, "unexpected token");
362 }
363
364 getParser().Lex(); // Consume the EndOfStatement.
365 return false;
366 }
367
368 bool MSP430AsmParser::ParseInstruction(ParseInstructionInfo &Info,
369 StringRef Name, SMLoc NameLoc,
370 OperandVector &Operands) {
371 // Drop .w suffix
372 if (Name.endswith_lower(".w"))
373 Name = Name.drop_back(2);
374
375 if (!parseJccInstruction(Info, Name, NameLoc, Operands))
376 return false;
377
378 // First operand is instruction mnemonic
379 Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc));
380
381 // If there are no more operands, then finish
382 if (getLexer().is(AsmToken::EndOfStatement))
383 return false;
384
385 // Parse first operand
386 if (ParseOperand(Operands))
387 return true;
388
389 // Parse second operand if any
390 if (getLexer().is(AsmToken::Comma)) {
391 getLexer().Lex(); // Eat ','
392 if (ParseOperand(Operands))
393 return true;
394 }
395
396 if (getLexer().isNot(AsmToken::EndOfStatement)) {
397 SMLoc Loc = getLexer().getLoc();
398 getParser().eatToEndOfStatement();
399 return Error(Loc, "unexpected token");
400 }
401
402 getParser().Lex(); // Consume the EndOfStatement.
403 return false;
404 }
405
406 bool MSP430AsmParser::ParseDirective(AsmToken DirectiveID) {
407 StringRef IDVal = DirectiveID.getIdentifier();
408 if (IDVal.lower() == ".long") {
409 ParseLiteralValues(4, DirectiveID.getLoc());
410 } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") {
411 ParseLiteralValues(2, DirectiveID.getLoc());
412 } else if (IDVal.lower() == ".byte") {
413 ParseLiteralValues(1, DirectiveID.getLoc());
414 }
415 return true;
416 }
417
418 bool MSP430AsmParser::ParseOperand(OperandVector &Operands) {
419 switch (getLexer().getKind()) {
420 default: return true;
421 case AsmToken::Identifier: {
422 // try rN
423 unsigned RegNo;
424 SMLoc StartLoc, EndLoc;
425 if (!ParseRegister(RegNo, StartLoc, EndLoc)) {
426 Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
427 return false;
428 }
429 LLVM_FALLTHROUGH;
430 }
431 case AsmToken::Integer:
432 case AsmToken::Plus:
433 case AsmToken::Minus: {
434 SMLoc StartLoc = getParser().getTok().getLoc();
435 const MCExpr *Val;
436 // Try constexpr[(rN)]
437 if (!getParser().parseExpression(Val)) {
438 unsigned RegNo = MSP430::PC;
439 SMLoc EndLoc = getParser().getTok().getLoc();
440 // Try (rN)
441 if (getLexer().getKind() == AsmToken::LParen) {
442 getLexer().Lex(); // Eat '('
443 SMLoc RegStartLoc;
444 if (ParseRegister(RegNo, RegStartLoc, EndLoc))
445 return true;
446 if (getLexer().getKind() != AsmToken::RParen)
447 return true;
448 EndLoc = getParser().getTok().getEndLoc();
449 getLexer().Lex(); // Eat ')'
450 }
451 Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
452 EndLoc));
453 return false;
454 }
455 return true;
456 }
457 case AsmToken::Amp: {
458 // Try &constexpr
459 SMLoc StartLoc = getParser().getTok().getLoc();
460 getLexer().Lex(); // Eat '&'
461 const MCExpr *Val;
462 if (!getParser().parseExpression(Val)) {
463 SMLoc EndLoc = getParser().getTok().getLoc();
464 Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
465 EndLoc));
466 return false;
467 }
468 return true;
469 }
470 case AsmToken::At: {
471 // Try @rN[+]
472 SMLoc StartLoc = getParser().getTok().getLoc();
473 getLexer().Lex(); // Eat '@'
474 unsigned RegNo;
475 SMLoc RegStartLoc, EndLoc;
476 if (ParseRegister(RegNo, RegStartLoc, EndLoc))
477 return true;
478 if (getLexer().getKind() == AsmToken::Plus) {
479 Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
480 getLexer().Lex(); // Eat '+'
481 return false;
482 }
483 Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
484 return false;
485 }
486 case AsmToken::Hash:
487 // Try #constexpr
488 SMLoc StartLoc = getParser().getTok().getLoc();
489 getLexer().Lex(); // Eat '#'
490 const MCExpr *Val;
491 if (!getParser().parseExpression(Val)) {
492 SMLoc EndLoc = getParser().getTok().getLoc();
493 Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
494 return false;
495 }
496 return true;
497 }
498 }
499
500 bool MSP430AsmParser::ParseLiteralValues(unsigned Size, SMLoc L) {
501 auto parseOne = [&]() -> bool {
502 const MCExpr *Value;
503 if (getParser().parseExpression(Value))
504 return true;
505 getParser().getStreamer().EmitValue(Value, Size, L);
506 return false;
507 };
508 return (parseMany(parseOne));
509 }
510
511 extern "C" void LLVMInitializeMSP430AsmParser() {
512 RegisterMCAsmParser X(getTheMSP430Target());
513 }
514
515 #define GET_REGISTER_MATCHER
516 #define GET_MATCHER_IMPLEMENTATION
517 #include "MSP430GenAsmMatcher.inc"
518
519 static unsigned convertGR16ToGR8(unsigned Reg) {
520 switch (Reg) {
521 default:
522 llvm_unreachable("Unknown GR16 register");
523 case MSP430::PC: return MSP430::PCB;
524 case MSP430::SP: return MSP430::SPB;
525 case MSP430::SR: return MSP430::SRB;
526 case MSP430::CG: return MSP430::CGB;
527 case MSP430::FP: return MSP430::FPB;
528 case MSP430::R5: return MSP430::R5B;
529 case MSP430::R6: return MSP430::R6B;
530 case MSP430::R7: return MSP430::R7B;
531 case MSP430::R8: return MSP430::R8B;
532 case MSP430::R9: return MSP430::R9B;
533 case MSP430::R10: return MSP430::R10B;
534 case MSP430::R11: return MSP430::R11B;
535 case MSP430::R12: return MSP430::R12B;
536 case MSP430::R13: return MSP430::R13B;
537 case MSP430::R14: return MSP430::R14B;
538 case MSP430::R15: return MSP430::R15B;
539 }
540 }
541
542 unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
543 unsigned Kind) {
544 MSP430Operand &Op = static_cast(AsmOp);
545
546 if (!Op.isReg())
547 return Match_InvalidOperand;
548
549 unsigned Reg = Op.getReg();
550 bool isGR16 =
551 MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg);
552
553 if (isGR16 && (Kind == MCK_GR8)) {
554 Op.setReg(convertGR16ToGR8(Reg));
555 return Match_Success;
556 }
557
558 return Match_InvalidOperand;
559 }
560
561 } // end of namespace llvm
0 set(LLVM_TARGET_DEFINITIONS MSP430.td)
11
2 tablegen(LLVM MSP430GenAsmMatcher.inc -gen-asm-matcher)
23 tablegen(LLVM MSP430GenAsmWriter.inc -gen-asm-writer)
34 tablegen(LLVM MSP430GenCallingConv.inc -gen-callingconv)
45 tablegen(LLVM MSP430GenDAGISel.inc -gen-dag-isel)
6 tablegen(LLVM MSP430GenDisassemblerTables.inc -gen-disassembler)
57 tablegen(LLVM MSP430GenInstrInfo.inc -gen-instr-info)
8 tablegen(LLVM MSP430GenMCCodeEmitter.inc -gen-emitter)
69 tablegen(LLVM MSP430GenRegisterInfo.inc -gen-register-info)
710 tablegen(LLVM MSP430GenSubtargetInfo.inc -gen-subtarget)
811
2528 add_subdirectory(InstPrinter)
2629 add_subdirectory(MCTargetDesc)
2730 add_subdirectory(TargetInfo)
31 add_subdirectory(AsmParser)
32 add_subdirectory(Disassembler)
0 add_llvm_library(LLVMMSP430Disassembler
1 MSP430Disassembler.cpp
2 )
0 ;====- lib/Target/MSP430/Disassembler/LLVMBuild.txt ------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = MSP430Disassembler
20 parent = MSP430
21 required_libraries = MCDisassembler MSP430Info Support
22 add_to_library_groups = MSP430
0 //===-- MSP430Disassembler.cpp - Disassembler for MSP430 ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the MSP430Disassembler class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "MSP430.h"
14 #include "MCTargetDesc/MSP430MCTargetDesc.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
17 #include "llvm/MC/MCFixedLenDisassembler.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/Endian.h"
22 #include "llvm/Support/TargetRegistry.h"
23
24 using namespace llvm;
25
26 #define DEBUG_TYPE "msp430-disassembler"
27
28 typedef MCDisassembler::DecodeStatus DecodeStatus;
29
30 namespace {
31 class MSP430Disassembler : public MCDisassembler {
32 DecodeStatus getInstructionI(MCInst &MI, uint64_t &Size,
33 ArrayRef Bytes, uint64_t Address,
34 raw_ostream &VStream,
35 raw_ostream &CStream) const;
36
37 DecodeStatus getInstructionII(MCInst &MI, uint64_t &Size,
38 ArrayRef Bytes, uint64_t Address,
39 raw_ostream &VStream,
40 raw_ostream &CStream) const;
41
42 DecodeStatus getInstructionCJ(MCInst &MI, uint64_t &Size,
43 ArrayRef Bytes, uint64_t Address,
44 raw_ostream &VStream,
45 raw_ostream &CStream) const;
46
47 public:
48 MSP430Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
49 : MCDisassembler(STI, Ctx) {}
50
51 DecodeStatus getInstruction(MCInst &MI, uint64_t &Size,
52 ArrayRef Bytes, uint64_t Address,
53 raw_ostream &VStream,
54 raw_ostream &CStream) const override;
55 };
56 } // end anonymous namespace
57
58 static MCDisassembler *createMSP430Disassembler(const Target &T,
59 const MCSubtargetInfo &STI,
60 MCContext &Ctx) {
61 return new MSP430Disassembler(STI, Ctx);
62 }
63
64 extern "C" void LLVMInitializeMSP430Disassembler() {
65 TargetRegistry::RegisterMCDisassembler(getTheMSP430Target(),
66 createMSP430Disassembler);
67 }
68
69 static const unsigned GR8DecoderTable[] = {
70 MSP430::PCB, MSP430::SPB, MSP430::SRB, MSP430::CGB,
71 MSP430::FPB, MSP430::R5B, MSP430::R6B, MSP430::R7B,
72 MSP430::R8B, MSP430::R9B, MSP430::R10B, MSP430::R11B,
73 MSP430::R12B, MSP430::R13B, MSP430::R14B, MSP430::R15B
74 };
75
76 static DecodeStatus DecodeGR8RegisterClass(MCInst &MI, uint64_t RegNo,
77 uint64_t Address,
78 const void *Decoder) {
79 if (RegNo > 15)
80 return MCDisassembler::Fail;
81
82 unsigned Reg = GR8DecoderTable[RegNo];
83 MI.addOperand(MCOperand::createReg(Reg));
84 return MCDisassembler::Success;
85 }
86
87 static const unsigned GR16DecoderTable[] = {
88 MSP430::PC, MSP430::SP, MSP430::SR, MSP430::CG,
89 MSP430::FP, MSP430::R5, MSP430::R6, MSP430::R7,
90 MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
91 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
92 };
93
94 static DecodeStatus DecodeGR16RegisterClass(MCInst &MI, uint64_t RegNo,
95 uint64_t Address,
96 const void *Decoder) {
97 if (RegNo > 15)
98 return MCDisassembler::Fail;
99
100 unsigned Reg = GR16DecoderTable[RegNo];
101 MI.addOperand(MCOperand::createReg(Reg));
102 return MCDisassembler::Success;
103 }
104
105 static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address,
106 const void *Decoder);
107
108 static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits,
109 uint64_t Address,
110 const void *Decoder);
111
112 #include "MSP430GenDisassemblerTables.inc"
113
114 static DecodeStatus DecodeCGImm(MCInst &MI, uint64_t Bits, uint64_t Address,
115 const void *Decoder) {
116 int64_t Imm;
117 switch (Bits) {
118 default:
119 llvm_unreachable("Invalid immediate value");
120 case 0x22: Imm = 4; break;
121 case 0x32: Imm = 8; break;
122 case 0x03: Imm = 0; break;
123 case 0x13: Imm = 1; break;
124 case 0x23: Imm = 2; break;
125 case 0x33: Imm = -1; break;
126 }
127 MI.addOperand(MCOperand::createImm(Imm));
128 return MCDisassembler::Success;
129 }
130
131 static DecodeStatus DecodeMemOperand(MCInst &MI, uint64_t Bits,
132 uint64_t Address,
133 const void *Decoder) {
134 unsigned Reg = Bits & 15;
135 unsigned Imm = Bits >> 4;
136
137 if (DecodeGR16RegisterClass(MI, Reg, Address, Decoder) !=
138 MCDisassembler::Success)
139 return MCDisassembler::Fail;
140
141 MI.addOperand(MCOperand::createImm((int16_t)Imm));
142 return MCDisassembler::Success;
143 }
144
145 enum AddrMode {
146 amInvalid = 0,
147 amRegister,
148 amIndexed,
149 amIndirect,
150 amIndirectPost,
151 amSymbolic,
152 amImmediate,
153 amAbsolute,
154 amConstant
155 };
156
157 static AddrMode DecodeSrcAddrMode(unsigned Rs, unsigned As) {
158 switch (Rs) {
159 case 0:
160 if (As == 1) return amSymbolic;
161 if (As == 2) return amInvalid;
162 if (As == 3) return amImmediate;
163 break;
164 case 2:
165 if (As == 1) return amAbsolute;
166 if (As == 2) return amConstant;
167 if (As == 3) return amConstant;
168 break;
169 case 3:
170 return amConstant;
171 default:
172 break;
173 }
174 switch (As) {
175 case 0: return amRegister;
176 case 1: return amIndexed;
177 case 2: return amIndirect;
178 case 3: return amIndirectPost;
179 default:
180 llvm_unreachable("As out of range");
181 }
182 }
183
184 static AddrMode DecodeSrcAddrModeI(unsigned Insn) {
185 unsigned Rs = fieldFromInstruction(Insn, 8, 4);
186 unsigned As = fieldFromInstruction(Insn, 4, 2);
187 return DecodeSrcAddrMode(Rs, As);
188 }
189
190 static AddrMode DecodeSrcAddrModeII(unsigned Insn) {
191 unsigned Rs = fieldFromInstruction(Insn, 0, 4);
192 unsigned As = fieldFromInstruction(Insn, 4, 2);
193 return DecodeSrcAddrMode(Rs, As);
194 }
195
196 static AddrMode DecodeDstAddrMode(unsigned Insn) {
197 unsigned Rd = fieldFromInstruction(Insn, 0, 4);
198 unsigned Ad = fieldFromInstruction(Insn, 7, 1);
199 switch (Rd) {
200 case 0: return Ad ? amSymbolic : amRegister;
201 case 2: return Ad ? amAbsolute : amRegister;
202 default:
203 break;
204 }
205 return Ad ? amIndexed : amRegister;
206 }
207
208 static const uint8_t *getDecoderTable(AddrMode SrcAM, unsigned Words) {
209 assert(0 < Words && Words < 4 && "Incorrect number of words");
210 switch (SrcAM) {
211 default:
212 llvm_unreachable("Invalid addressing mode");
213 case amRegister:
214 assert(Words < 3 && "Incorrect number of words");
215 return Words == 2 ? DecoderTableAlpha32 : DecoderTableAlpha16;
216 case amConstant:
217 assert(Words < 3 && "Incorrect number of words");
218 return Words == 2 ? DecoderTableBeta32 : DecoderTableBeta16;
219 case amIndexed:
220 case amSymbolic:
221 case amImmediate:
222 case amAbsolute:
223 assert(Words > 1 && "Incorrect number of words");
224 return Words == 2 ? DecoderTableGamma32 : DecoderTableGamma48;
225 case amIndirect:
226 case amIndirectPost:
227 assert(Words < 3 && "Incorrect number of words");
228 return Words == 2 ? DecoderTableDelta32 : DecoderTableDelta16;
229 }
230 }
231
232 DecodeStatus MSP430Disassembler::getInstructionI(MCInst &MI, uint64_t &Size,
233 ArrayRef Bytes,
234 uint64_t Address,
235 raw_ostream &VStream,
236 raw_ostream &CStream) const {
237 uint64_t Insn = support::endian::read16le(Bytes.data());
238 AddrMode SrcAM = DecodeSrcAddrModeI(Insn);
239 AddrMode DstAM = DecodeDstAddrMode(Insn);
240 if (SrcAM == amInvalid || DstAM == amInvalid) {
241 Size = 2; // skip one word and let disassembler to try further
242 return MCDisassembler::Fail;
243 }
244
245 unsigned Words = 1;
246 switch (SrcAM) {
247 case amIndexed:
248 case amSymbolic:
249 case amImmediate:
250 case amAbsolute:
251 Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
252 ++Words;
253 break;
254 default:
255 break;
256 }
257 switch (DstAM) {
258 case amIndexed:
259 case amSymbolic:
260 case amAbsolute:
261 Insn |= (uint64_t)support::endian::read16le(Bytes.data() + Words * 2)
262 << (Words * 16);
263 ++Words;
264 break;
265 default:
266 break;
267 }
268
269 DecodeStatus Result = decodeInstruction(getDecoderTable(SrcAM, Words), MI,
270 Insn, Address, this, STI);
271 if (Result != MCDisassembler::Fail) {
272 Size = Words * 2;
273 return Result;
274 }
275
276 Size = 2;
277 return DecodeStatus::Fail;
278 }
279
280 DecodeStatus MSP430Disassembler::getInstructionII(MCInst &MI, uint64_t &Size,
281 ArrayRef Bytes,
282 uint64_t Address,
283 raw_ostream &VStream,
284 raw_ostream &CStream) const {
285 uint64_t Insn = support::endian::read16le(Bytes.data());
286 AddrMode SrcAM = DecodeSrcAddrModeII(Insn);
287 if (SrcAM == amInvalid) {
288 Size = 2; // skip one word and let disassembler to try further
289 return MCDisassembler::Fail;
290 }
291
292 unsigned Words = 1;
293 switch (SrcAM) {
294 case amIndexed:
295 case amSymbolic:
296 case amImmediate:
297 case amAbsolute:
298 Insn |= (uint64_t)support::endian::read16le(Bytes.data() + 2) << 16;
299 ++Words;
300 break;
301 default:
302 break;
303 }
304
305 const uint8_t *DecoderTable = Words == 2 ? DecoderTable32 : DecoderTable16;
306 DecodeStatus Result = decodeInstruction(DecoderTable, MI, Insn, Address,
307 this, STI);
308 if (Result != MCDisassembler::Fail) {
309 Size = Words * 2;
310 return Result;
311 }
312
313 Size = 2;
314 return DecodeStatus::Fail;
315 }
316
317 static MSP430CC::CondCodes getCondCode(unsigned Cond) {
318 switch (Cond) {
319 case 0: return MSP430CC::COND_NE;
320 case 1: return MSP430CC::COND_E;
321 case 2: return MSP430CC::COND_LO;
322 case 3: return MSP430CC::COND_HS;
323 case 4: return MSP430CC::COND_N;
324 case 5: return MSP430CC::COND_GE;
325 case 6: return MSP430CC::COND_L;
326 case 7: return MSP430CC::COND_NONE;
327 default:
328 llvm_unreachable("Cond out of range");
329 }
330 }
331
332 DecodeStatus MSP430Disassembler::getInstructionCJ(MCInst &MI, uint64_t &Size,
333 ArrayRef Bytes,
334 uint64_t Address,
335 raw_ostream &VStream,
336 raw_ostream &CStream) const {
337 uint64_t Insn = support::endian::read16le(Bytes.data());
338 unsigned Cond = fieldFromInstruction(Insn, 10, 3);
339 unsigned Offset = fieldFromInstruction(Insn, 0, 10);
340
341 MI.addOperand(MCOperand::createImm(SignExtend32(Offset, 10)));
342
343 if (Cond == 7)
344 MI.setOpcode(MSP430::JMP);
345 else {
346 MI.setOpcode(MSP430::JCC);
347 MI.addOperand(MCOperand::createImm(getCondCode(Cond)));
348 }
349
350 Size = 2;
351 return DecodeStatus::Success;
352 }
353
354 DecodeStatus MSP430Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
355 ArrayRef Bytes,
356 uint64_t Address,
357 raw_ostream &VStream,
358 raw_ostream &CStream) const {
359 if (Bytes.size() < 2) {
360 Size = 0;
361 return MCDisassembler::Fail;
362 }
363
364 uint64_t Insn = support::endian::read16le(Bytes.data());
365 unsigned Opc = fieldFromInstruction(Insn, 13, 3);
366 switch (Opc) {
367 case 0:
368 return getInstructionII(MI, Size, Bytes, Address, VStream, CStream);
369 case 1:
370 return getInstructionCJ(MI, Size, Bytes, Address, VStream, CStream);
371 default:
372 return getInstructionI(MI, Size, Bytes, Address, VStream, CStream);
373 }
374 }
1515 #include "llvm/MC/MCAsmInfo.h"
1616 #include "llvm/MC/MCExpr.h"
1717 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrInfo.h"
1819 #include "llvm/Support/ErrorHandling.h"
1920 #include "llvm/Support/FormattedStream.h"
2021 using namespace llvm;
2122
2223 #define DEBUG_TYPE "asm-printer"
2324
24
2525 // Include the auto-generated portion of the assembly writer.
26 #define PRINT_ALIAS_INSTR
2627 #include "MSP430GenAsmWriter.inc"
2728
2829 void MSP430InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
2930 StringRef Annot, const MCSubtargetInfo &STI) {
30 printInstruction(MI, O);
31 if (!printAliasInstr(MI, O))
32 printInstruction(MI, O);
3133 printAnnotation(O, Annot);
3234 }
3335
3436 void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo,
3537 raw_ostream &O) {
3638 const MCOperand &Op = MI->getOperand(OpNo);
37 if (Op.isImm())
38 O << Op.getImm();
39 else {
39 if (Op.isImm()) {
40 int64_t Imm = Op.getImm() * 2 + 2;
41 O << "$";
42 if (Imm >= 0)
43 O << '+';
44 O << Imm;
45 } else {
4046 assert(Op.isExpr() && "unknown pcrel immediate operand");
4147 Op.getExpr()->print(O, &MAI);
4248 }
7177 // vs
7278 // mov.w glb(r1), r2
7379 // Otherwise (!) msp430-as will silently miscompile the output :(
74 if (!Base.getReg())
80 if (Base.getReg() == MSP430::SR)
7581 O << '&';
7682
7783 if (Disp.isExpr())
8288 }
8389
8490 // Print register base field
85 if (Base.getReg())
91 if ((Base.getReg() != MSP430::SR) &&
92 (Base.getReg() != MSP430::PC))
8693 O << '(' << getRegisterName(Base.getReg()) << ')';
94 }
95
96 void MSP430InstPrinter::printIndRegOperand(const MCInst *MI, unsigned OpNo,
97 raw_ostream &O) {
98 const MCOperand &Base = MI->getOperand(OpNo);
99 O << "@" << getRegisterName(Base.getReg());
100 }
101
102 void MSP430InstPrinter::printPostIndRegOperand(const MCInst *MI, unsigned OpNo,
103 raw_ostream &O) {
104 const MCOperand &Base = MI->getOperand(OpNo);
105 O << "@" << getRegisterName(Base.getReg()) << "+";
87106 }
88107
89108 void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo,
111130 case MSP430CC::COND_L:
112131 O << 'l';
113132 break;
133 case MSP430CC::COND_N:
134 O << 'n';
135 break;
114136 }
115137 }
2727
2828 // Autogenerated by tblgen.
2929 void printInstruction(const MCInst *MI, raw_ostream &O);
30 bool printAliasInstr(const MCInst *MI, raw_ostream &O);
31 void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx,
32 unsigned PrintMethodIdx, raw_ostream &O);
3033 static const char *getRegisterName(unsigned RegNo);
3134
35 private:
3236 void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
3337 const char *Modifier = nullptr);
3438 void printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
3539 void printSrcMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
3640 const char *Modifier = nullptr);
41 void printIndRegOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
42 void printPostIndRegOperand(const MCInst *MI, unsigned OpNo,
43 raw_ostream &O);
3744 void printCCOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
3845
3946 };
1515 ;===------------------------------------------------------------------------===;
1616
1717 [common]
18 subdirectories = InstPrinter MCTargetDesc TargetInfo
18 subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
1919
2020 [component_0]
2121 type = TargetGroup
2222 name = MSP430
2323 parent = Target
24 has_asmparser = 1
2425 has_asmprinter = 1
26 has_disassembler = 1
2527
2628 [component_1]
2729 type = Library
0 add_llvm_library(LLVMMSP430Desc
1 MSP430AsmBackend.cpp
2 MSP430ELFObjectWriter.cpp
3 MSP430ELFStreamer.cpp
4 MSP430MCAsmInfo.cpp
5 MSP430MCCodeEmitter.cpp
16 MSP430MCTargetDesc.cpp
2 MSP430MCAsmInfo.cpp
37 )
0 //===-- MSP430AsmBackend.cpp - MSP430 Assembler Backend -------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "MCTargetDesc/MSP430FixupKinds.h"
10 #include "MCTargetDesc/MSP430MCTargetDesc.h"
11 #include "llvm/ADT/APInt.h"
12 #include "llvm/MC/MCAsmBackend.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCDirectives.h"
16 #include "llvm/MC/MCELFObjectWriter.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCFixupKindInfo.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCTargetOptions.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
25
26 using namespace llvm;
27
28 namespace {
29 class MSP430AsmBackend : public MCAsmBackend {
30 uint8_t OSABI;
31
32 uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
33 MCContext &Ctx) const;
34
35 public:
36 MSP430AsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI)
37 : MCAsmBackend(support::little), OSABI(OSABI) {}
38 ~MSP430AsmBackend() override {}
39
40 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
41 const MCValue &Target, MutableArrayRef Data,
42 uint64_t Value, bool IsResolved,
43 const MCSubtargetInfo *STI) const override;
44
45 std::unique_ptr
46 createObjectTargetWriter() const override {
47 return createMSP430ELFObjectWriter(OSABI);
48 }
49
50 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
51 const MCRelaxableFragment *DF,
52 const MCAsmLayout &Layout) const override {
53 return false;
54 }
55
56 bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
57 uint64_t Value,
58 const MCRelaxableFragment *DF,
59 const MCAsmLayout &Layout,
60 const bool WasForced) const override {
61 return false;
62 }
63
64 unsigned getNumFixupKinds() const override {
65 return MSP430::NumTargetFixupKinds;
66 }
67
68 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
69 const static MCFixupKindInfo Infos[MSP430::NumTargetFixupKinds] = {
70 // This table must be in the same order of enum in MSP430FixupKinds.h.
71 //
72 // name offset bits flags
73 {"fixup_32", 0, 32, 0},
74 {"fixup_10_pcrel", 0, 10, MCFixupKindInfo::FKF_IsPCRel},
75 {"fixup_16", 0, 16, 0},
76 {"fixup_16_pcrel", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
77 {"fixup_16_byte", 0, 16, 0},
78 {"fixup_16_pcrel_byte", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
79 {"fixup_2x_pcrel", 0, 10, MCFixupKindInfo::FKF_IsPCRel},
80 {"fixup_rl_pcrel", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
81 {"fixup_8", 0, 8, 0},
82 {"fixup_sym_diff", 0, 32, 0},
83 };
84 static_assert((array_lengthof(Infos)) == MSP430::NumTargetFixupKinds,
85 "Not all fixup kinds added to Infos array");
86
87 if (Kind < FirstTargetFixupKind)
88 return MCAsmBackend::getFixupKindInfo(Kind);
89
90 return Infos[Kind - FirstTargetFixupKind];
91 }
92
93 bool mayNeedRelaxation(const MCInst &Inst,
94 const MCSubtargetInfo &STI) const override {
95 return false;
96 }
97
98 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
99 MCInst &Res) const override {}
100
101 bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
102 };
103
104 uint64_t MSP430AsmBackend::adjustFixupValue(const MCFixup &Fixup,
105 uint64_t Value,
106 MCContext &Ctx) const {
107 unsigned Kind = Fixup.getKind();
108 switch (Kind) {
109 case MSP430::fixup_10_pcrel: {
110 if (Value & 0x1)
111 Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");
112
113 // Offset is signed
114 int16_t Offset = Value;
115 // Jumps are in words
116 Offset >>= 1;
117 // PC points to the next instruction so decrement by one
118 --Offset;
119
120 if (Offset < -512 || Offset > 511)
121 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
122
123 // Mask 10 bits
124 Offset &= 0x3ff;
125
126 return Offset;
127 }
128 default:
129 return Value;
130 }
131 }
132
133 void MSP430AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
134 const MCValue &Target,
135 MutableArrayRef Data,
136 uint64_t Value, bool IsResolved,
137 const MCSubtargetInfo *STI) const {
138 Value = adjustFixupValue(Fixup, Value, Asm.getContext());
139 MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
140 if (!Value)
141 return; // Doesn't change encoding.
142
143 // Shift the value into position.
144 Value <<= Info.TargetOffset;
145
146 unsigned Offset = Fixup.getOffset();
147 unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8;
148
149 assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
150
151 // For each byte of the fragment that the fixup touches, mask in the
152 // bits from the fixup value.
153 for (unsigned i = 0; i != NumBytes; ++i) {
154 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
155 }
156 }
157
158 bool MSP430AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
159 if ((Count % 2) != 0)
160 return false;
161
162 // The canonical nop on MSP430 is mov #0, r3
163 uint64_t NopCount = Count / 2;
164 while (NopCount--)
165 OS.write("\x03\x43", 2);
166
167 return true;
168 }
169
170 } // end anonymous namespace
171
172 MCAsmBackend *llvm::createMSP430MCAsmBackend(const Target &T,
173 const MCSubtargetInfo &STI,
174 const MCRegisterInfo &MRI,
175 const MCTargetOptions &Options) {
176 return new MSP430AsmBackend(STI, ELF::ELFOSABI_STANDALONE);
177 }
0 //===-- MSP430ELFObjectWriter.cpp - MSP430 ELF Writer ---------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "MCTargetDesc/MSP430FixupKinds.h"
10 #include "MCTargetDesc/MSP430MCTargetDesc.h"
11
12 #include "MCTargetDesc/MSP430MCTargetDesc.h"
13 #include "llvm/MC/MCELFObjectWriter.h"
14 #include "llvm/MC/MCFixup.h"
15 #include "llvm/MC/MCObjectWriter.h"
16 #include "llvm/MC/MCValue.h"
17 #include "llvm/Support/ErrorHandling.h"
18
19 using namespace llvm;
20
21 namespace {
22 class MSP430ELFObjectWriter : public MCELFObjectTargetWriter {
23 public:
24 MSP430ELFObjectWriter(uint8_t OSABI)
25 : MCELFObjectTargetWriter(false, OSABI, ELF::EM_MSP430,
26 /*HasRelocationAddend*/ true) {}
27
28 ~MSP430ELFObjectWriter() override {}
29
30 protected:
31 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
32 const MCFixup &Fixup, bool IsPCRel) const override {
33 // Translate fixup kind to ELF relocation type.
34 switch ((unsigned)Fixup.getKind()) {
35 case FK_Data_1: return ELF::R_MSP430_8;
36 case FK_Data_2: return ELF::R_MSP430_16;
37 case FK_Data_4: return ELF::R_MSP430_32;
38 case MSP430::fixup_32: return ELF::R_MSP430_32;
39 case MSP430::fixup_10_pcrel: return ELF::R_MSP430_10_PCREL;
40 case MSP430::fixup_16: return ELF::R_MSP430_16;
41 case MSP430::fixup_16_pcrel: return ELF::R_MSP430_16_PCREL;
42 case MSP430::fixup_16_byte: return ELF::R_MSP430_16_BYTE;
43 case MSP430::fixup_16_pcrel_byte: return ELF::R_MSP430_16_PCREL_BYTE;
44 case MSP430::fixup_2x_pcrel: return ELF::R_MSP430_2X_PCREL;
45 case MSP430::fixup_rl_pcrel: return ELF::R_MSP430_RL_PCREL;
46 case MSP430::fixup_8: return ELF::R_MSP430_8;
47 case MSP430::fixup_sym_diff: return ELF::R_MSP430_SYM_DIFF;
48 default:
49 llvm_unreachable("Invalid fixup kind");
50 }
51 }
52 };
53 } // end of anonymous namespace
54
55 std::unique_ptr
56 llvm::createMSP430ELFObjectWriter(uint8_t OSABI) {
57 return llvm::make_unique(OSABI);
58 }
0 //===-- MSP430ELFStreamer.cpp - MSP430 ELF Target Streamer Methods --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides MSP430 specific target streamer methods.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "MSP430MCTargetDesc.h"
14 #include "llvm/BinaryFormat/ELF.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCELFStreamer.h"
17 #include "llvm/MC/MCSectionELF.h"
18 #include "llvm/MC/MCStreamer.h"
19 #include "llvm/MC/MCSubtargetInfo.h"
20
21 using namespace llvm;
22
23 namespace llvm {
24
25 class MSP430TargetELFStreamer : public MCTargetStreamer {
26 public:
27 MCELFStreamer &getStreamer();
28 MSP430TargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
29 };
30
31 // This part is for ELF object output.
32 MSP430TargetELFStreamer::MSP430TargetELFStreamer(MCStreamer &S,
33 const MCSubtargetInfo &STI)
34 : MCTargetStreamer(S) {
35 MCAssembler &MCA = getStreamer().getAssembler();
36 unsigned EFlags = MCA.getELFHeaderEFlags();
37 MCA.setELFHeaderEFlags(EFlags);
38
39 // Emit build attributes section according to
40 // MSP430 EABI (slaa534.pdf, part 13).
41 MCSection *AttributeSection = getStreamer().getContext().getELFSection(
42 ".MSP430.attributes", ELF::SHT_MSP430_ATTRIBUTES, 0);
43 Streamer.SwitchSection(AttributeSection);
44
45 // Format version.
46 Streamer.EmitIntValue(0x41, 1);
47 // Subsection length.
48 Streamer.EmitIntValue(22, 4);
49 // Vendor name string, zero-terminated.
50 Streamer.EmitBytes("mspabi");
51 Streamer.EmitIntValue(0, 1);
52
53 // Attribute vector scope tag. 1 stands for the entire file.
54 Streamer.EmitIntValue(1, 1);
55 // Attribute vector length.
56 Streamer.EmitIntValue(11, 4);
57 // OFBA_MSPABI_Tag_ISA(4) = 1, MSP430
58 Streamer.EmitIntValue(4, 1);
59 Streamer.EmitIntValue(1, 1);
60 // OFBA_MSPABI_Tag_Code_Model(6) = 1, Small
61 Streamer.EmitIntValue(6, 1);
62 Streamer.EmitIntValue(1, 1);
63 // OFBA_MSPABI_Tag_Data_Model(8) = 1, Small
64 Streamer.EmitIntValue(8, 1);
65 Streamer.EmitIntValue(1, 1);
66 }
67
68 MCELFStreamer &MSP430TargetELFStreamer::getStreamer() {
69 return static_cast(Streamer);
70 }
71
72 MCTargetStreamer *
73 createMSP430ObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
74 const Triple &TT = STI.getTargetTriple();
75 if (TT.isOSBinFormatELF())
76 return new MSP430TargetELFStreamer(S, STI);
77 return nullptr;
78 }
79
80 } // namespace llvm
0 //===-- MSP430FixupKinds.h - MSP430 Specific Fixup Entries ------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430FIXUPKINDS_H
10 #define LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430FIXUPKINDS_H
11
12 #include "llvm/MC/MCFixup.h"
13
14 #undef MSP430
15
16 namespace llvm {
17 namespace MSP430 {
18
19 // This table must be in the same order of
20 // MCFixupKindInfo Infos[MSP430::NumTargetFixupKinds]
21 // in MSP430AsmBackend.cpp.
22 //
23 enum Fixups {
24 // A 32 bit absolute fixup.
25 fixup_32 = FirstTargetFixupKind,
26 // A 10 bit PC relative fixup.
27 fixup_10_pcrel,
28 // A 16 bit absolute fixup.
29 fixup_16,
30 // A 16 bit PC relative fixup.
31 fixup_16_pcrel,
32 // A 16 bit absolute fixup for byte operations.
33 fixup_16_byte,
34 // A 16 bit PC relative fixup for command address.
35 fixup_16_pcrel_byte,
36 // A 10 bit PC relative fixup for complicated polymorphs.
37 fixup_2x_pcrel,
38 // A 16 bit relaxable fixup.
39 fixup_rl_pcrel,
40 // A 8 bit absolute fixup.
41 fixup_8,
42 // A 32 bit symbol difference fixup.
43 fixup_sym_diff,
44
45 // Marker
46 LastTargetFixupKind,
47 NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
48 };
49 } // end namespace MSP430
50 } // end namespace llvm
51
52 #endif
0 //===-- MSP430MCCodeEmitter.cpp - Convert MSP430 code to machine code -----===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the MSP430MCCodeEmitter class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "MSP430.h"
14 #include "MCTargetDesc/MSP430MCTargetDesc.h"
15 #include "MCTargetDesc/MSP430FixupKinds.h"
16
17 #include "llvm/ADT/APFloat.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCFixup.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/Support/Endian.h"
28 #include "llvm/Support/EndianStream.h"
29 #include "llvm/Support/raw_ostream.h"
30
31 #define DEBUG_TYPE "mccodeemitter"
32
33 namespace llvm {
34
35 class MSP430MCCodeEmitter : public MCCodeEmitter {
36 MCContext &Ctx;
37 MCInstrInfo const &MCII;
38
39 // Offset keeps track of current word number being emitted
40 // inside a particular instruction.
41 mutable unsigned Offset;
42
43 /// TableGen'erated function for getting the binary encoding for an
44 /// instruction.
45 uint64_t getBinaryCodeForInstr(const MCInst &MI,
46 SmallVectorImpl &Fixups,
47 const MCSubtargetInfo &STI) const;
48
49 /// Returns the binary encoding of operands.
50 ///
51 /// If an operand requires relocation, the relocation is recorded
52 /// and zero is returned.
53 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
54 SmallVectorImpl &Fixups,
55 const MCSubtargetInfo &STI) const;
56
57 unsigned getMemOpValue(const MCInst &MI, unsigned Op,
58 SmallVectorImpl &Fixups,
59 const MCSubtargetInfo &STI) const;
60
61 unsigned getPCRelImmOpValue(const MCInst &MI, unsigned Op,
62 SmallVectorImpl &Fixups,
63 const MCSubtargetInfo &STI) const;
64
65 unsigned getCGImmOpValue(const MCInst &MI, unsigned Op,
66 SmallVectorImpl &Fixups,
67 const MCSubtargetInfo &STI) const;
68
69 unsigned getCCOpValue(const MCInst &MI, unsigned Op,
70 SmallVectorImpl &Fixups,
71 const MCSubtargetInfo &STI) const;
72
73 public:
74 MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
75 : Ctx(ctx), MCII(MCII) {}
76
77 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
78 SmallVectorImpl &Fixups,
79 const MCSubtargetInfo &STI) const override;
80 };
81
82 void MSP430MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
83 SmallVectorImpl &Fixups,
84 const MCSubtargetInfo &STI) const {
85 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
86 // Get byte count of instruction.
87 unsigned Size = Desc.getSize();
88
89 // Initialize fixup offset
90 Offset = 2;
91
92 uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);
93 const uint16_t *Words = reinterpret_cast(&BinaryOpCode);
94 size_t WordCount = Size / 2;
95
96 for (size_t i = 0; i < WordCount; ++i) {
97 uint16_t Word = Words[i];
98 support::endian::write(OS, Word, support::little);
99 }
100 }
101
102 unsigned MSP430MCCodeEmitter::getMachineOpValue(const MCInst &MI,
103 const MCOperand &MO,
104 SmallVectorImpl &Fixups,
105 const MCSubtargetInfo &STI) const {
106 if (MO.isReg())
107 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
108
109 if (MO.isImm()) {
110 Offset += 2;
111 return MO.getImm();
112 }
113
114 assert(MO.isExpr() && "Expected expr operand");
115 Fixups.push_back(MCFixup::create(Offset, MO.getExpr(),
116 static_cast(MSP430::fixup_16_byte), MI.getLoc()));
117 Offset += 2;
118 return 0;
119 }
120
121 unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op,
122 SmallVectorImpl &Fixups,
123 const MCSubtargetInfo &STI) const {
124 const MCOperand &MO1 = MI.getOperand(Op);
125 assert(MO1.isReg() && "Register operand expected");
126 unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
127
128 const MCOperand &MO2 = MI.getOperand(Op + 1);
129 if (MO2.isImm()) {
130 Offset += 2;
131 return (MO2.getImm() << 4) | Reg;
132 }
133
134 assert(MO2.isExpr() && "Expr operand expected");
135 MSP430::Fixups FixupKind;
136 switch (Reg) {
137 case 0:
138 FixupKind = MSP430::fixup_16_pcrel_byte;
139 break;
140 case 2:
141 FixupKind = MSP430::fixup_16_byte;
142 break;
143 default:
144 FixupKind = MSP430::fixup_16_byte;
145 break;
146 }
147 Fixups.push_back(MCFixup::create(Offset, MO2.getExpr(),
148 static_cast(FixupKind), MI.getLoc()));
149 Offset += 2;
150 return Reg;
151 }
152
153 unsigned MSP430MCCodeEmitter::getPCRelImmOpValue(const MCInst &MI, unsigned Op,
154 SmallVectorImpl &Fixups,
155 const MCSubtargetInfo &STI) const {
156 const MCOperand &MO = MI.getOperand(Op);
157 if (MO.isImm())
158 return MO.getImm();
159
160 assert(MO.isExpr() && "Expr operand expected");
161 Fixups.push_back(MCFixup::create(0, MO.getExpr(),
162 static_cast(MSP430::fixup_10_pcrel), MI.getLoc()));
163 return 0;
164 }
165
166 unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op,
167 SmallVectorImpl &Fixups,
168 const MCSubtargetInfo &STI) const {
169 const MCOperand &MO = MI.getOperand(Op);
170 assert(MO.isImm() && "Expr operand expected");
171
172 int64_t Imm = MO.getImm();
173 switch (Imm) {
174 default:
175 llvm_unreachable("Invalid immediate value");
176 case 4: return 0x22;
177 case 8: return 0x32;
178 case 0: return 0x03;
179 case 1: return 0x13;
180 case 2: return 0x23;
181 case -1: return 0x33;
182 }
183 }
184
185 unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
186 SmallVectorImpl &Fixups,
187 const MCSubtargetInfo &STI) const {
188 const MCOperand &MO = MI.getOperand(Op);
189 assert(MO.isImm() && "Immediate operand expected");
190 switch (MO.getImm()) {
191 case MSP430CC::COND_NE: return 0;
192 case MSP430CC::COND_E: return 1;
193 case MSP430CC::COND_LO: return 2;
194 case MSP430CC::COND_HS: return 3;
195 case MSP430CC::COND_N: return 4;
196 case MSP430CC::COND_GE: return 5;
197 case MSP430CC::COND_L: return 6;
198 default:
199 llvm_unreachable("Unknown condition code");
200 }
201 }
202
203 MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII,
204 const MCRegisterInfo &MRI,
205 MCContext &Ctx) {
206 return new MSP430MCCodeEmitter(Ctx, MCII);
207 }
208
209 #include "MSP430GenMCCodeEmitter.inc"
210
211 } // end of namespace llvm
5757 }
5858
5959 extern "C" void LLVMInitializeMSP430TargetMC() {
60 // Register the MC asm info.
61 RegisterMCAsmInfo X(getTheMSP430Target());
60 Target &T = getTheMSP430Target();
6261
63 // Register the MC instruction info.
64 TargetRegistry::RegisterMCInstrInfo(getTheMSP430Target(),
65 createMSP430MCInstrInfo);
66
67 // Register the MC register info.
68 TargetRegistry::RegisterMCRegInfo(getTheMSP430Target(),
69 createMSP430MCRegisterInfo);
70
71 // Register the MC subtarget info.
72 TargetRegistry::RegisterMCSubtargetInfo(getTheMSP430Target(),
73 createMSP430MCSubtargetInfo);
74
75 // Register the MCInstPrinter.
76 TargetRegistry::RegisterMCInstPrinter(getTheMSP430Target(),
77 createMSP430MCInstPrinter);
62 RegisterMCAsmInfo X(T);
63 TargetRegistry::RegisterMCInstrInfo(T, createMSP430MCInstrInfo);
64 TargetRegistry::RegisterMCRegInfo(T, createMSP430MCRegisterInfo);
65 TargetRegistry::RegisterMCSubtargetInfo(T, createMSP430MCSubtargetInfo);
66 TargetRegistry::RegisterMCInstPrinter(T, createMSP430MCInstPrinter);
67 TargetRegistry::RegisterMCCodeEmitter(T, createMSP430MCCodeEmitter);
68 TargetRegistry::RegisterMCAsmBackend(T, createMSP430MCAsmBackend);
69 TargetRegistry::RegisterObjectTargetStreamer(
70 T, createMSP430ObjectTargetStreamer);
7871 }
1414 #define LLVM_LIB_TARGET_MSP430_MCTARGETDESC_MSP430MCTARGETDESC_H
1515
1616 #include "llvm/Support/DataTypes.h"
17 #include
1718
1819 namespace llvm {
1920 class Target;
21 class MCAsmBackend;
22 class MCCodeEmitter;
23 class MCInstrInfo;
24 class MCSubtargetInfo;
25 class MCRegisterInfo;
26 class MCContext;
27 class MCTargetOptions;
28 class MCObjectTargetWriter;
29 class MCStreamer;
30 class MCTargetStreamer;
2031
2132 Target &getTheMSP430Target();
33
34 /// Creates a machine code emitter for MSP430.
35 MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII,
36 const MCRegisterInfo &MRI,
37 MCContext &Ctx);
38
39 MCAsmBackend *createMSP430MCAsmBackend(const Target &T,
40 const MCSubtargetInfo &STI,
41 const MCRegisterInfo &MRI,
42 const MCTargetOptions &Options);
43
44 MCTargetStreamer *
45 createMSP430ObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
46
47 std::unique_ptr
48 createMSP430ELFObjectWriter(uint8_t OSABI);
2249
2350 } // End llvm namespace
2451
2626 COND_LO = 3, // aka COND_NC
2727 COND_GE = 4,
2828 COND_L = 5,
29 COND_N = 6, // jump if negative
30 COND_NONE, // unconditional
2931
3032 COND_INVALID = -1
3133 };
6363
6464 def MSP430InstrInfo : InstrInfo;
6565
66 //===---------------------------------------------------------------------===//
67 // Assembly Printers
68 //===---------------------------------------------------------------------===//
69
70 def MSP430AsmWriter : AsmWriter {
71 string AsmWriterClassName = "InstPrinter";
72 }
73
74 //===---------------------------------------------------------------------===//
75 // Assembly Parsers
76 //===---------------------------------------------------------------------===//
77
78 def MSP430AsmParser : AsmParser {
79 let AllowDuplicateRegisterNames = 1;
80 let ShouldEmitMatchRegisterAltName = 1;
81 }
82
6683 //===----------------------------------------------------------------------===//
6784 // Target Declaration
6885 //===----------------------------------------------------------------------===//
6986
7087 def MSP430 : Target {
7188 let InstructionSet = MSP430InstrInfo;
89 let AssemblyParsers = [MSP430AsmParser];
7290 }
7391
9797 MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
9898 : SelectionDAGISel(TM, OptLevel) {}
9999
100 private:
100101 StringRef getPassName() const override {
101102 return "MSP430 DAG->DAG Pattern Instruction Selection";
102103 }
111112 // Include the pieces autogenerated from the target description.
112113 #include "MSP430GenDAGISel.inc"
113114
114 private:
115 // Main method to transform nodes into machine nodes.
115116 void Select(SDNode *N) override;
117
116118 bool tryIndexedLoad(SDNode *Op);
117119 bool tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8,
118120 unsigned Opc16);
249251 if (MatchAddress(N, AM))
250252 return false;
251253
252 EVT VT = N.getValueType();
253 if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
254 if (AM.BaseType == MSP430ISelAddressMode::RegBase)
254255 if (!AM.Base.Reg.getNode())
255 AM.Base.Reg = CurDAG->getRegister(0, VT);
256 }
256 AM.Base.Reg = CurDAG->getRegister(MSP430::SR, MVT::i16);
257257
258258 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase)
259259 ? CurDAG->getTargetFrameIndex(
335335 unsigned Opcode = 0;
336336 switch (VT.SimpleTy) {
337337 case MVT::i8:
338 Opcode = MSP430::MOV8rm_POST;
338 Opcode = MSP430::MOV8rp;
339339 break;
340340 case MVT::i16:
341 Opcode = MSP430::MOV16rm_POST;
341 Opcode = MSP430::MOV16rp;
342342 break;
343343 default:
344344 return false;
411411 break;
412412 case ISD::ADD:
413413 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
414 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
414 MSP430::ADD8rp, MSP430::ADD16rp))
415415 return;
416416 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
417 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
417 MSP430::ADD8rp, MSP430::ADD16rp))
418418 return;
419419
420420 // Other cases are autogenerated.
421421 break;
422422 case ISD::SUB:
423423 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
424 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
424 MSP430::SUB8rp, MSP430::SUB16rp))
425425 return;
426426
427427 // Other cases are autogenerated.
428428 break;
429429 case ISD::AND:
430430 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
431 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
431 MSP430::AND8rp, MSP430::AND16rp))
432432 return;
433433 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
434 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
434 MSP430::AND8rp, MSP430::AND16rp))
435435 return;
436436
437437 // Other cases are autogenerated.
438438 break;
439439 case ISD::OR:
440440 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
441 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
441 MSP430::BIS8rp, MSP430::BIS16rp))
442442 return;
443443 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
444 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
444 MSP430::BIS8rp, MSP430::BIS16rp))
445445 return;
446446
447447 // Other cases are autogenerated.
448448 break;
449449 case ISD::XOR:
450450 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1),
451 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
451 MSP430::XOR8rp, MSP430::XOR16rp))
452452 return;
453453 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
454 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
454 MSP430::XOR8rp, MSP430::XOR16rp))
455455 return;
456456
457457 // Other cases are autogenerated.
939939
940940 // Expand non-constant shifts to loops:
941941 if (!isa(N->getOperand(1)))
942 switch (Opc) {
943 default: llvm_unreachable("Invalid shift opcode!");
944 case ISD::SHL:
945 return DAG.getNode(MSP430ISD::SHL, dl,
946 VT, N->getOperand(0), N->getOperand(1));
947 case ISD::SRA:
948 return DAG.getNode(MSP430ISD::SRA, dl,
949 VT, N->getOperand(0), N->getOperand(1));
950 case ISD::SRL:
951 return DAG.getNode(MSP430ISD::SRL, dl,
952 VT, N->getOperand(0), N->getOperand(1));
953 }
942 return Op;
954943
955944 uint64_t ShiftAmount = cast(N->getOperand(1))->getZExtValue();
956945
962951 if (Opc == ISD::SRL && ShiftAmount) {
963952 // Emit a special goodness here:
964953 // srl A, 1 => clrc; rrc A
965 Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
954 Victim = DAG.getNode(MSP430ISD::RRCL, dl, VT, Victim);
966955 ShiftAmount -= 1;
967956 }
968957
13411330 case MSP430ISD::RRA: return "MSP430ISD::RRA";
13421331 case MSP430ISD::RLA: return "MSP430ISD::RLA";
13431332 case MSP430ISD::RRC: return "MSP430ISD::RRC";
1333 case MSP430ISD::RRCL: return "MSP430ISD::RRCL";
13441334 case MSP430ISD::CALL: return "MSP430ISD::CALL";
13451335 case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
13461336 case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC";
13471337 case MSP430ISD::CMP: return "MSP430ISD::CMP";
13481338 case MSP430ISD::SETCC: return "MSP430ISD::SETCC";
13491339 case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC";
1350 case MSP430ISD::SHL: return "MSP430ISD::SHL";
1351 case MSP430ISD::SRA: return "MSP430ISD::SRA";
1352 case MSP430ISD::SRL: return "MSP430ISD::SRL";
1340 case MSP430ISD::DADD: return "MSP430ISD::DADD";
13531341 }
13541342 return nullptr;
13551343 }
13961384 const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
13971385
13981386 unsigned Opc;
1387 bool ClearCarry = false;
13991388 const TargetRegisterClass * RC;
14001389 switch (MI.getOpcode()) {
14011390 default: llvm_unreachable("Invalid shift opcode!");
14021391 case MSP430::Shl8:
1403 Opc = MSP430::SHL8r1;
1404 RC = &MSP430::GR8RegClass;
1405 break;
1392 Opc = MSP430::ADD8rr;
1393 RC = &MSP430::GR8RegClass;
1394 break;
14061395 case MSP430::Shl16:
1407 Opc = MSP430::SHL16r1;
1408 RC = &MSP430::GR16RegClass;
1409 break;
1396 Opc = MSP430::ADD16rr;
1397 RC = &MSP430::GR16RegClass;
1398 break;
14101399 case MSP430::Sra8:
1411 Opc = MSP430::SAR8r1;
1412 RC = &MSP430::GR8RegClass;
1413 break;
1400 Opc = MSP430::RRA8r;
1401 RC = &MSP430::GR8RegClass;
1402 break;
14141403 case MSP430::Sra16:
1415 Opc = MSP430::SAR16r1;
1416 RC = &MSP430::GR16RegClass;
1417 break;
1404 Opc = MSP430::RRA16r;
1405 RC = &MSP430::GR16RegClass;
1406 break;
14181407 case MSP430::Srl8:
1419 Opc = MSP430::SAR8r1c;
1420 RC = &MSP430::GR8RegClass;
1421 break;
1408 ClearCarry = true;
1409 Opc = MSP430::RRC8r;
1410 RC = &MSP430::GR8RegClass;
1411 break;
14221412 case MSP430::Srl16:
1423 Opc = MSP430::SAR16r1c;
1424 RC = &MSP430::GR16RegClass;
1425 break;
1413 ClearCarry = true;
1414 Opc = MSP430::RRC16r;
1415 RC = &MSP430::GR16RegClass;
1416 break;
1417 case MSP430::Rrcl8:
1418 case MSP430::Rrcl16: {
1419 BuildMI(*BB, MI, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1420 .addReg(MSP430::SR).addImm(1);
1421 unsigned SrcReg = MI.getOperand(1).getReg();
1422 unsigned DstReg = MI.getOperand(0).getReg();
1423 unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16
1424 ? MSP430::RRC16r : MSP430::RRC8r;
1425 BuildMI(*BB, MI, dl, TII.get(RrcOpc), DstReg)
1426 .addReg(SrcReg);
1427 MI.eraseFromParent(); // The pseudo instruction is gone now.
1428 return BB;
1429 }
14261430 }
14271431
14281432 const BasicBlock *LLVM_BB = BB->getBasicBlock();
14751479 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
14761480 .addReg(ShiftAmtSrcReg).addMBB(BB)
14771481 .addReg(ShiftAmtReg2).addMBB(LoopBB);
1478 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1479 .addReg(ShiftReg);
1482 if (ClearCarry)
1483 BuildMI(LoopBB, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1484 .addReg(MSP430::SR).addImm(1);
1485 if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr)
1486 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1487 .addReg(ShiftReg)
1488 .addReg(ShiftReg);
1489 else
1490 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1491 .addReg(ShiftReg);
14801492 BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
14811493 .addReg(ShiftAmtReg).addImm(1);
14821494 BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
14981510 MachineBasicBlock *BB) const {
14991511 unsigned Opc = MI.getOpcode();
15001512
1501 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1502 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1503 Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1513 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1514 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1515 Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
1516 Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
15041517 return EmitShiftInstr(MI, BB);
15051518
15061519 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
3535 /// Y = RRC X, rotate right via carry
3636 RRC,
3737
38 /// Rotate right via carry, carry gets cleared beforehand by clrc
39 RRCL,
40
3841 /// CALL - These operations represent an abstract call
3942 /// instruction, which includes a bunch of information.
4043 CALL,
6063 /// is condition code and operand 4 is flag operand.
6164 SELECT_CC,
6265
63 /// SHL, SRA, SRL - Non-constant shifts.
64 SHL, SRA, SRL
66 /// DADD - Decimal addition with carry
67 /// TODO Nothing generates a node of this type yet.
68 DADD,
6569 };
6670 }
6771
1010 // Describe MSP430 instructions format here
1111 //
1212
13 // Format specifies the encoding used by the instruction. This is part of the
14 // ad-hoc solution used to emit machine instruction encodings by our machine
15 // code emitter.
16 class Format val> {
17 bits<2> Value = val;
18 }
19
20 def PseudoFrm : Format<0>;
21 def SingleOpFrm : Format<1>;
22 def DoubleOpFrm : Format<2>;
23 def CondJumpFrm : Format<3>;
24
2513 class SourceMode val> {
2614 bits<2> Value = val;
2715 }
2816
29 def SrcReg : SourceMode<0>;
30 def SrcMem : SourceMode<1>;
31 def SrcIndReg : SourceMode<2>;
32 def SrcPostInc : SourceMode<3>;
33 def SrcImm : SourceMode<3>;
17 def SrcReg : SourceMode<0>; // r
18 def SrcMem : SourceMode<1>; // m
19 def SrcIndReg : SourceMode<2>; // n
20 def SrcPostInc : SourceMode<3>; // p
21 def SrcImm : SourceMode<3>; // i
22 // SrcCGImm : SourceMode< >; // c
3423
3524 class DestMode {
3625 bit Value = val;
3726 }
3827
39 def DstReg : DestMode<0>;
40 def DstMem : DestMode<1>;
41
42 class SizeVal val> {
43 bits<3> Value = val;
44 }
45
46 def SizeUnknown : SizeVal<0>; // Unknown / unset size
47 def SizeSpecial : SizeVal<1>; // Special instruction, e.g. pseudo
48 def Size2Bytes : SizeVal<2>;
49 def Size4Bytes : SizeVal<3>;
50 def Size6Bytes : SizeVal<4>;
28 def DstReg : DestMode<0>; // r
29 def DstMem : DestMode<1>; // m
5130
5231 // Generic MSP430 Format
53 class MSP430Inst
54 string asmstr> : Instruction {
55 field bits<16> Inst;
32 class MSP430Inst : Instruction {
33 field bits<48> Inst;
34 field bits<48> SoftFail = 0;
5635
5736 let Namespace = "MSP430";
5837
5938 dag OutOperandList = outs;
6039 dag InOperandList = ins;
6140
62 Format Form = f;
63 SizeVal Sz = sz;
64
65 // Define how we want to layout our TargetSpecific information field... This
66 // should be kept up-to-date with the fields in the MSP430InstrInfo.h file.
67 let TSFlags{1-0} = Form.Value;
68 let TSFlags{4-2} = Sz.Value;
69
70 let AsmString = asmstr;
71 }
72
73 // FIXME: Create different classes for different addressing modes.
41 let AsmString = asmstr;
42 let Size = size;
43 }
7444
7545 // MSP430 Double Operand (Format I) Instructions
76 class IForm opcode, DestMode dest, bit bw, SourceMode src, SizeVal sz,
77 dag outs, dag ins, string asmstr, list pattern>
78 : MSP430Inst {
79 let Pattern = pattern;
80
81 DestMode ad = dest;
82 SourceMode as = src;
83
84 let Inst{12-15} = opcode;
46 class IForm opcode, DestMode ad, bit bw, SourceMode as, int size,
47 dag outs, dag ins, string asmstr, list pattern>
48 : MSP430Inst {
49 let Pattern = pattern;
50
51 bits<4> rs;
52 bits<4> rd;
53
54 let Inst{15-12} = opcode;
55 let Inst{11-8} = rs;
8556 let Inst{7} = ad.Value;
8657 let Inst{6} = bw;
87 let Inst{4-5} = as.Value;
58 let Inst{5-4} = as.Value;
59 let Inst{3-0} = rd;
8860 }
8961
9062 // 8 bit IForm instructions
91 class IForm8 opcode, DestMode dest, SourceMode src, SizeVal sz,
63 class IForm8 opcode, DestMode dest, SourceMode src, int size,
9264 dag outs, dag ins, string asmstr, list pattern>
93 : IFormz, outs, ins, asmstr, pattern>;
65 : IFormize, outs, ins, asmstr, pattern>;
9466
9567 class I8rr opcode,
9668 dag outs, dag ins, string asmstr, list pattern>
97 : IForm8Size2Bytes, outs, ins, asmstr, pattern>;
69 : IForm82, outs, ins, asmstr, pattern> {
70 let DecoderNamespace = "Alpha";
71 }
9872
9973 class I8ri opcode,
10074 dag outs, dag ins, string asmstr, list pattern>
101 : IForm8Size4Bytes, outs, ins, asmstr, pattern>;
75 : IForm84, outs, ins, asmstr, pattern> {
76 let DecoderNamespace = "Gamma";
77 bits<16> imm;
78 let Inst{31-16} = imm;
79 let rs = 0b0000;
80 }
81
82 class I8rc opcode,
83 dag outs, dag ins, string asmstr, list pattern>
84 : MSP430Inst {
85 let DecoderNamespace = "Beta";
86 let Pattern = pattern;
87
88 bits<6> imm;
89 bits<4> rd;
90
91 let Inst{15-12} = opcode;
92 let Inst{11-8} = imm{3-0};
93 let Inst{7} = DstReg.Value;
94 let Inst{6} = 1;
95 let Inst{5-4} = imm{5-4};
96 let Inst{3-0} = rd;
97 }
10298
10399 class I8rm opcode,
104100 dag outs, dag ins, string asmstr, list pattern>
105 : IForm8Size4Bytes, outs, ins, asmstr, pattern>;
101 : IForm84, outs, ins, asmstr, pattern> {
102 let DecoderNamespace = "Gamma";
103 bits<20> src;
104 let rs = src{3-0};
105 let Inst{31-16} = src{19-4};
106 }
107
108 class I8rn opcode,
109 dag outs, dag ins, string asmstr, list pattern>
110 : IForm8 {
111 let DecoderNamespace = "Delta";
112 }
113
114 class I8rp opcode,
115 dag outs, dag ins, string asmstr, list pattern>
116 : IForm8 {
117 let DecoderNamespace = "Delta";
118 }
106119
107120 class I8mr opcode,
108121 dag outs, dag ins, string asmstr, list pattern>
109 : IForm8Size4Bytes, outs, ins, asmstr, pattern>;
122 : IForm84, outs, ins, asmstr, pattern> {
123 let DecoderNamespace = "Alpha";
124 bits<20> dst;
125 let rd = dst{3-0};
126 let Inst{31-16} = dst{19-4};
127 }
110128
111129 class I8mi opcode,
112130 dag outs, dag ins, string asmstr, list pattern>
113 : IForm8Size6Bytes, outs, ins, asmstr, pattern>;
131 : IForm86, outs, ins, asmstr, pattern> {
132 let DecoderNamespace = "Gamma";
133 bits<16> imm;
134 bits<20> dst;
135 let rs = 0b0000;
136 let Inst{31-16} = imm;
137 let rd = dst{3-0};
138 let Inst{47-32} = dst{19-4};
139 }
140
141 class I8mc opcode,
142 dag outs, dag ins, string asmstr, list pattern>
143 : MSP430Inst {
144 let DecoderNamespace = "Beta";
145 let Pattern = pattern;
146
147 bits<6> imm;
148 bits<20> dst;
149
150 let Inst{31-16} = dst{19-4};
151 let Inst{15-12} = opcode;
152 let Inst{11-8} = imm{3-0};
153 let Inst{7} = DstMem.Value;
154 let Inst{6} = 1;
155 let Inst{5-4} = imm{5-4};
156 let Inst{3-0} = dst{3-0};
157 }
114158
115159 class I8mm opcode,
116160 dag outs, dag ins, string asmstr, list pattern>
117 : IForm8Size6Bytes, outs, ins, asmstr, pattern>;
161 : IForm86, outs, ins, asmstr, pattern> {
162 let DecoderNamespace = "Gamma";
163 bits<20> src;
164 bits<20> dst;
165 let rs = src{3-0};
166 let Inst{31-16} = src{19-4};
167 let rd = dst{3-0};
168 let Inst{47-32} = dst{19-4};
169 }
170
171 class I8mn opcode,
172 dag outs, dag ins, string asmstr, list pattern>
173 : IForm8 {
174 let DecoderNamespace = "Delta";
175 bits<20> dst;
176 let rd = dst{3-0};
177 let Inst{31-16} = dst{19-4};
178 }
179
180 class I8mp opcode,
181 dag outs, dag ins, string asmstr, list pattern>
182 : IForm8 {
183 let DecoderNamespace = "Delta";
184 bits<20> dst;
185 let rd = dst{3-0};
186 let Inst{31-16} = dst{19-4};
187 }
118188
119189 // 16 bit IForm instructions
120 class IForm16 opcode, DestMode dest, SourceMode src, SizeVal sz,
190 class IForm16 opcode, DestMode dest, SourceMode src, int size,
121191 dag outs, dag ins, string asmstr, list pattern>
122 : IFormz, outs, ins, asmstr, pattern>;
192 : IFormize, outs, ins, asmstr, pattern>;
123193
124194 class I16rr opcode,
125195 dag outs, dag ins, string asmstr, list pattern>
126 : IForm16Size2Bytes, outs, ins, asmstr, pattern>;
196 : IForm162, outs, ins, asmstr, pattern> {
197 let DecoderNamespace = "Alpha";
198 }
127199
128200 class I16ri opcode,
129201 dag outs, dag ins, string asmstr, list pattern>
130 : IForm16Size4Bytes, outs, ins, asmstr, pattern>;
202 : IForm164, outs, ins, asmstr, pattern> {
203 let DecoderNamespace = "Gamma";
204 bits<16> imm;
205 let Inst{31-16} = imm;
206 let rs = 0b0000;
207 }
208
209 class I16rc opcode,
210 dag outs, dag ins, string asmstr, list pattern>
211 : MSP430Inst {
212 let DecoderNamespace = "Beta";
213 let Pattern = pattern;
214
215 bits<6> imm;
216 bits<4> rd;
217
218 let Inst{15-12} = opcode;
219 let Inst{11-8} = imm{3-0};
220 let Inst{7} = DstReg.Value;
221 let Inst{6} = 0;
222 let Inst{5-4} = imm{5-4};
223 let Inst{3-0} = rd;
224 }
131225
132226 class I16rm opcode,
133227 dag outs, dag ins, string asmstr, list pattern>
134 : IForm16Size4Bytes, outs, ins, asmstr, pattern>;
228 : IForm164, outs, ins, asmstr, pattern> {
229 let DecoderNamespace = "Gamma";
230 bits<20> src;
231 let rs = src{3-0};
232 let Inst{31-16} = src{19-4};
233 }
234
235 class I16rn opcode,
236 dag outs, dag ins, string asmstr, list pattern>
237 : IForm16 {
238 let DecoderNamespace = "Delta";
239 }
240
241 class I16rp opcode,
242 dag outs, dag ins, string asmstr, list pattern>
243 : IForm16 {
244 let DecoderNamespace = "Delta";
245 }
135246
136247 class I16mr opcode,
137248 dag outs, dag ins, string asmstr, list pattern>
138 : IForm16Size4Bytes, outs, ins, asmstr, pattern>;
249 : IForm164, outs, ins, asmstr, pattern> {
250 let DecoderNamespace = "Alpha";
251 bits<20> dst;
252 let rd = dst{3-0};
253 let Inst{31-16} = dst{19-4};
254 }
139255
140256 class I16mi opcode,
141257 dag outs, dag ins, string asmstr, list pattern>
142 : IForm16Size6Bytes, outs, ins, asmstr, pattern>;
258 : IForm166, outs, ins, asmstr, pattern> {
259 let DecoderNamespace = "Gamma";
260 bits<16> imm;
261 bits<20> dst;
262 let Inst{31-16} = imm;
263 let rs = 0b0000;
264 let rd = dst{3-0};
265 let Inst{47-32} = dst{19-4};
266 }
267
268 class I16mc opcode,
269 dag outs, dag ins, string asmstr, list pattern>
270 : MSP430Inst {
271 let DecoderNamespace = "Beta";
272 let Pattern = pattern;
273
274 bits<6> imm;
275 bits<20> dst;
276
277 let Inst{31-16} = dst{19-4};
278 let Inst{15-12} = opcode;
279 let Inst{11-8} = imm{3-0};
280 let Inst{7} = DstMem.Value;
281 let Inst{6} = 0;
282 let Inst{5-4} = imm{5-4};
283 let Inst{3-0} = dst{3-0};
284 }
143285
144286 class I16mm opcode,
145287 dag outs, dag ins, string asmstr, list pattern>
146 : IForm16Size6Bytes, outs, ins, asmstr, pattern>;
288 : IForm166, outs, ins, asmstr, pattern> {
289 let DecoderNamespace = "Gamma";
290 bits<20> src;
291 bits<20> dst;
292 let rs = src{3-0};
293 let Inst{31-16} = src{19-4};
294 let rd = dst{3-0};
295 let Inst{47-32} = dst{19-4};
296 }
297
298 class I16mn opcode,
299 dag outs, dag ins, string asmstr, list pattern>
300 : IForm16 {
301 let DecoderNamespace = "Delta";
302 bits<20> dst;
303 let rd = dst{3-0};
304 let Inst{31-16} = dst{19-4};
305 }
306
307 class I16mp opcode,
308 dag outs, dag ins, string asmstr, list pattern>
309 : IForm16 {
310 let DecoderNamespace = "Delta";
311 bits<20> dst;
312 let rd = dst{3-0};
313 let Inst{31-16} = dst{19-4};
314 }
147315
148316 // MSP430 Single Operand (Format II) Instructions
149 class IIForm9> opcode, bit bw, SourceMode src, SizeVal sz,
317 class IIForm3> opcode, bit bw, SourceMode as, int size,
150318 dag outs, dag ins, string asmstr, list pattern>
151 : MSP430Instz, SingleOpFrm, asmstr> {
319 : MSP430Instize, asmstr> {
320 let Pattern = pattern;
321
322 bits<4> rs;
323
324 let Inst{15-10} = 0b000100;
325 let Inst{9-7} = opcode;
326 let Inst{6} = bw;
327 let Inst{5-4} = as.Value;
328 let Inst{3-0} = rs;
329 }
330
331 // 8 bit IIForm instructions
332 class IIForm8 opcode, SourceMode src, int size,
333 dag outs, dag ins, string asmstr, list pattern>
334 : IIForm;
335
336 class II8r opcode,
337 dag outs, dag ins, string asmstr, list pattern>
338 : IIForm8;
339
340 class II8m opcode,
341 dag outs, dag ins, string asmstr, list pattern>
342 : IIForm8 {
343 bits<20> src;
344 let rs = src{3-0};
345 let Inst{31-16} = src{19-4};
346 }
347
348 class II8i opcode,
349 dag outs, dag ins, string asmstr, list pattern>
350 : IIForm8 {
351 bits<16> imm;
352 let rs = 0b0000;
353 let Inst{31-16} = imm;
354 }
355
356 class II8c opcode,
357 dag outs, dag ins, string asmstr, list pattern>
358 : MSP430Inst {
359 let Pattern = pattern;
360
361 bits<6> imm;
362
363 let Inst{15-10} = 0b000100;
364 let Inst{9-7} = opcode;
365 let Inst{6} = 1;
366 let Inst{5-0} = imm;
367 }
368
369 class II8n opcode,
370 dag outs, dag ins, string asmstr, list pattern>
371 : IIForm8;
372
373 class II8p opcode,
374 dag outs, dag ins, string asmstr, list pattern>
375 : IIForm8;
376
377 // 16 bit IIForm instructions
378 class IIForm16 opcode, SourceMode src, int size,
379 dag outs, dag ins, string asmstr, list pattern>
380 : IIForm;
381
382 class II16r opcode,
383 dag outs, dag ins, string asmstr, list pattern>
384 : IIForm16;
385
386 class II16m opcode,
387 dag outs, dag ins, string asmstr, list pattern>
388 : IIForm16 {
389 bits<20> src;
390 let rs = src{3-0};
391 let Inst{31-16} = src{19-4};
392 }
393
394 class II16i opcode,
395 dag outs, dag ins, string asmstr, list pattern>
396 : IIForm16 {
397 bits<16> imm;
398 let rs = 0b0000;
399 let Inst{31-16} = imm;
400 }
401
402 class II16c opcode,
403 dag outs, dag ins, string asmstr, list pattern>
404 : MSP430Inst {
405 let Pattern = pattern;
406
407 bits<6> imm;
408
409 let Inst{15-10} = 0b000100;
410 let Inst{9-7} = opcode;
411 let Inst{6} = 0;
412 let Inst{5-0} = imm;
413 }
414
415 class II16n opcode,
416 dag outs, dag ins, string asmstr, list pattern>
417 : IIForm16;
418
419 class II16p opcode,
420 dag outs, dag ins, string asmstr, list pattern>
421 : IIForm16;
422
423 // MSP430 Conditional Jumps Instructions
424 class CJForm pattern>
425 : MSP430Inst {
152426 let Pattern = pattern;
153427
154 SourceMode as = src;
155
156 let Inst{7-15} = opcode;
157 let Inst{6} = bw;
158 let Inst{4-5} = as.Value;
159 }
160
161 // 8 bit IIForm instructions
162 class IIForm8 opcode, SourceMode src, SizeVal sz,
163 dag outs, dag ins, string asmstr, list pattern>
164 : IIForm;
165
166 class II8r opcode,
167 dag outs, dag ins, string asmstr, list pattern>
168 : IIForm8;
169
170 class II8m opcode,
171 dag outs, dag ins, string asmstr, list pattern>
172 : IIForm8;
173
174 class II8i opcode,
175 dag outs, dag ins, string asmstr, list pattern>
176 : IIForm8;
177
178 // 16 bit IIForm instructions
179 class IIForm16 opcode, SourceMode src, SizeVal sz,
180 dag outs, dag ins, string asmstr, list pattern>
181 : IIForm;
182
183 class II16r opcode,
184 dag outs, dag ins, string asmstr, list pattern>
185 : IIForm16;
186
187 class II16m opcode,
188 dag outs, dag ins, string asmstr, list pattern>
189 : IIForm16;
190
191 class II16i opcode,
192 dag outs, dag ins, string asmstr, list pattern>
193 : IIForm16;
194
195 // MSP430 Conditional Jumps Instructions
196 class CJForm opcode, bits<3> cond,
197 dag outs, dag ins, string asmstr, list pattern>
198 : MSP430Inst {
199 let Pattern = pattern;
200
201 let Inst{13-15} = opcode;
202 let Inst{10-12} = cond;
428 bits<3> cond;
429 bits<10> dst;
430
431 let Inst{15-13} = 0b001;
432 let Inst{12-10} = cond;
433 let Inst{9-0} = dst;
203434 }
204435
205436 // Pseudo instructions
206437 class Pseudo pattern>
207 : MSP430Inst {
208 let Pattern = pattern;
209 let Inst{15-0} = 0;
210 }
438 : MSP430Inst {
439 let Pattern = pattern;
440 }
300300 unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
301301 const MCInstrDesc &Desc = MI.getDesc();
302302
303 switch (Desc.TSFlags & MSP430II::SizeMask) {
304 default:
305 switch (Desc.getOpcode()) {
306 default: llvm_unreachable("Unknown instruction size!");
307 case TargetOpcode::CFI_INSTRUCTION:
308 case TargetOpcode::EH_LABEL:
309 case TargetOpcode::IMPLICIT_DEF:
310 case TargetOpcode::KILL:
311 case TargetOpcode::DBG_VALUE:
312 return 0;
313 case TargetOpcode::INLINEASM: {
314 const MachineFunction *MF = MI.getParent()->getParent();
315 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
316 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
317 *MF->getTarget().getMCAsmInfo());
318 }
319 }
320 case MSP430II::SizeSpecial:
321 switch (MI.getOpcode()) {
322 default: llvm_unreachable("Unknown instruction size!");
323 case MSP430::SAR8r1c:
324 case MSP430::SAR16r1c:
325 return 4;
326 }
327 case MSP430II::Size2Bytes:
328 return 2;
329 case MSP430II::Size4Bytes:
330 return 4;
331 case MSP430II::Size6Bytes:
332 return 6;
333 }
334 }
303 switch (Desc.getOpcode()) {
304 case TargetOpcode::CFI_INSTRUCTION:
305 case TargetOpcode::EH_LABEL:
306 case TargetOpcode::IMPLICIT_DEF:
307 case TargetOpcode::KILL:
308 case TargetOpcode::DBG_VALUE:
309 return 0;
310 case TargetOpcode::INLINEASM: {
311 const MachineFunction *MF = MI.getParent()->getParent();
312 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
313 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
314 *MF->getTarget().getMCAsmInfo());
315 }
316 }
317
318 return Desc.getSize();
319 }
2222 namespace llvm {
2323
2424 class MSP430Subtarget;
25
26 /// MSP430II - This namespace holds all of the target specific flags that
27 /// instruction info tracks.
28 ///
29 namespace MSP430II {
30 enum {
31 SizeShift = 2,
32 SizeMask = 7 << SizeShift,
33
34 SizeUnknown = 0 << SizeShift,
35 SizeSpecial = 1 << SizeShift,
36 Size2Bytes = 2 << SizeShift,
37 Size4Bytes = 3 << SizeShift,
38 Size6Bytes = 4 << SizeShift
39 };
40 }
4125
4226 class MSP430InstrInfo : public MSP430GenInstrInfo {
4327 const MSP430RegisterInfo RI;
3333 def SDT_MSP430SelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
3434 SDTCisSameAs<1, 2>,
3535 SDTCisVT<3, i8>]>;
36 def SDT_MSP430Shift : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
37 SDTCisI8<2>]>;
36 def SDT_MSP430DAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
37 SDTCisSameAs<0, 2>,
38 SDTCisInt<0>]>;
3839
3940 //===----------------------------------------------------------------------===//
4041 // MSP430 Specific Node Definitions.
4748 def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
4849 def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
4950 def MSP430rrc : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>;
51 def MSP430rrcl : SDNode<"MSP430ISD::RRCL", SDTIntUnaryOp, []>;
5052
5153 def MSP430call : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
5254 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
6264 [SDNPHasChain, SDNPInGlue]>;
6365 def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC,
6466 [SDNPInGlue]>;
65 def MSP430shl : SDNode<"MSP430ISD::SHL", SDT_MSP430Shift, []>;
66 def MSP430sra : SDNode<"MSP430ISD::SRA", SDT_MSP430Shift, []>;
67 def MSP430srl : SDNode<"MSP430ISD::SRL", SDT_MSP430Shift, []>;
67 def MSP430dadd : SDNode<"MSP430ISD::DADD", SDT_MSP430DAdd, []>;
6868
6969 //===----------------------------------------------------------------------===//
7070 // MSP430 Operand Definitions.
7171 //===----------------------------------------------------------------------===//
72
73 def MemAsmOperand : AsmOperandClass {
74 let Name = "Mem";
75 }
7276
7377 // Address operands
7478 def memsrc : Operand {
7579 let PrintMethod = "printSrcMemOperand";
7680 let MIOperandInfo = (ops GR16, i16imm);
81 let ParserMatchClass = MemAsmOperand;
82 let EncoderMethod = "getMemOpValue";
83 let DecoderMethod = "DecodeMemOperand";
7784 }
7885
7986 def memdst : Operand {
8087 let PrintMethod = "printSrcMemOperand";
8188 let MIOperandInfo = (ops GR16, i16imm);
89 let ParserMatchClass = MemAsmOperand;
90 let EncoderMethod = "getMemOpValue";
91 let DecoderMethod = "DecodeMemOperand";
92 }
93
94 def IndRegAsmOperand : AsmOperandClass {
95 let Name = "IndReg";
96 let RenderMethod = "addRegOperands";
97 }
98
99 def indreg : Operand {
100 let PrintMethod = "printIndRegOperand";
101 let MIOperandInfo = (ops GR16);
102 let ParserMatchClass = IndRegAsmOperand;
103 let DecoderMethod = "DecodeGR16RegisterClass";
104 }
105
106 def PostIndRegAsmOperand : AsmOperandClass {
107 let Name = "PostIndReg";
108 let RenderMethod = "addRegOperands";
109 }
110
111 def postreg : Operand {
112 let PrintMethod = "printPostIndRegOperand";
113 let MIOperandInfo = (ops GR16);
114 let ParserMatchClass = PostIndRegAsmOperand;
115 let DecoderMethod = "DecodeGR16RegisterClass";
82116 }
83117
84118 // Short jump targets have OtherVT type and are printed as pcrel imm values.
85119 def jmptarget : Operand {
86120 let PrintMethod = "printPCRelImmOperand";
121 let EncoderMethod = "getPCRelImmOpValue";
87122 }
88123
89124 // Operand for printing out a condition code.
90125 def cc : Operand {
91126 let PrintMethod = "printCCOperand";
127 let EncoderMethod = "getCCOpValue";
128 }
129
130 def CGImmAsmOperand : AsmOperandClass {
131 let Name = "CGImm";
132 let RenderMethod = "addImmOperands";
133 }
134
135 def cg8imm : Operand,
136 ImmLeaf
137 Imm == 4 || Imm == 8 || Imm == -1;}]> {
138 let ParserMatchClass = CGImmAsmOperand;
139 let EncoderMethod = "getCGImmOpValue";
140 let DecoderMethod = "DecodeCGImm";
141 }
142
143 def cg16imm : Operand,
144 ImmLeaf
145 Imm == 4 || Imm == 8 || Imm == -1;}]> {
146 let ParserMatchClass = CGImmAsmOperand;
147 let EncoderMethod = "getCGImmOpValue";
148 let DecoderMethod = "DecodeCGImm";
92149 }
93150
94151 //===----------------------------------------------------------------------===//
101158 // Pattern Fragments
102159 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
103160 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
161 def bic : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, (not node:$rhs))>;
104162 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
105163 return N->hasOneUse();
106164 }]>;
112170 // pointer before prolog-epilog rewriting occurs.
113171 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
114172 // sub / add which can clobber SR.
115 let Defs = [SP, SR], Uses = [SP] in {
173 let isCodeGenOnly = 1, Defs = [SP, SR], Uses = [SP] in {
116174 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
117 "#ADJCALLSTACKDOWN",
175 "#ADJCALLSTACKDOWN $amt1 $amt2",
118176 [(MSP430callseq_start timm:$amt1, timm:$amt2)]>;
119177 def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
120 "#ADJCALLSTACKUP",
178 "#ADJCALLSTACKUP $amt1 $amt2",
121179 [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
122180 }
123181
124 let Defs = [SR], Uses = [SP] in {
182 let isCodeGenOnly = 1, Defs = [SR], Uses = [SP] in {
125183 def ADDframe : Pseudo<(outs GR16:$dst), (ins i16imm:$base, i16imm:$offset),
126184 "# ADDframe PSEUDO", []>;
127185 }
128186
129 let usesCustomInserter = 1 in {
187 let isCodeGenOnly = 1, usesCustomInserter = 1 in {
130188 let Uses = [SR] in {
131189 def Select8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$src2, i8imm:$cc),
132190 "# Select8 PSEUDO",
140198 let Defs = [SR] in {
141199 def Shl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt),
142200 "# Shl8 PSEUDO",
143 [(set GR8:$dst, (MSP430shl GR8:$src, GR8:$cnt))]>;
201 [(set GR8:$dst, (shl GR8:$src, GR8:$cnt))]>;
144202 def Shl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt),
145203 "# Shl16 PSEUDO",
146 [(set GR16:$dst, (MSP430shl GR16:$src, GR8:$cnt))]>;
204 [(set GR16:$dst, (shl GR16:$src, GR8:$cnt))]>;
147205 def Sra8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt),
148206 "# Sra8 PSEUDO",
149 [(set GR8:$dst, (MSP430sra GR8:$src, GR8:$cnt))]>;
207 [(set GR8:$dst, (sra GR8:$src, GR8:$cnt))]>;
150208 def Sra16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt),
151209 "# Sra16 PSEUDO",
152 [(set GR16:$dst, (MSP430sra GR16:$src, GR8:$cnt))]>;
210 [(set GR16:$dst, (sra GR16:$src, GR8:$cnt))]>;
153211 def Srl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt),
154212 "# Srl8 PSEUDO",
155 [(set GR8:$dst, (MSP430srl GR8:$src, GR8:$cnt))]>;
213 [(set GR8:$dst, (srl GR8:$src, GR8:$cnt))]>;
156214 def Srl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt),
157215 "# Srl16 PSEUDO",
158 [(set GR16:$dst, (MSP430srl GR16:$src, GR8:$cnt))]>;
159
216 [(set GR16:$dst, (srl GR16:$src, GR8:$cnt))]>;
217 def Rrcl8 : Pseudo<(outs GR8:$dst), (ins GR8:$src), "",
218 [(set GR8:$dst, (MSP430rrcl GR8:$src))]>;
219 def Rrcl16 : Pseudo<(outs GR16:$dst), (ins GR16:$src), "",
220 [(set GR16:$dst, (MSP430rrcl GR16:$src))]>;
160221 }
161222 }
162
163 let hasSideEffects = 0 in
164 def NOP : Pseudo<(outs), (ins), "nop", []>;
165223
166224 //===----------------------------------------------------------------------===//
167225 // Control Flow Instructions...
169227
170228 // FIXME: Provide proper encoding!
171229 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
172 def RET : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
173 (outs), (ins), "ret", [(MSP430retflag)]>;
174 def RETI : II16r<0x0, (outs), (ins), "reti", [(MSP430retiflag)]>;
230 def RET : IForm16<0b0100, DstReg, SrcPostInc, 2,
231 (outs), (ins), "ret", [(MSP430retflag)]> {
232 let DecoderNamespace = "Delta";
233 let rs = 1;
234 let rd = 0;
235 }
236 def RETI : IIForm16<0b110, SrcReg, 2,
237 (outs), (ins), "reti", [(MSP430retiflag)]> {
238 let rs = 0;
239 }
175240 }
176241
177242 let isBranch = 1, isTerminator = 1 in {
181246 // Direct branch
182247 let isBarrier = 1 in {
183248 // Short branch
184 def JMP : CJForm<0, 0, (outs), (ins jmptarget:$dst),
249 def JMP : CJForm<(outs), (ins jmptarget:$dst),
185250 "jmp\t$dst",
186 [(br bb:$dst)]>;
187 let isIndirectBranch = 1 in {
251 [(br bb:$dst)]> {
252 let cond = 0b111;
253 }
254 let isIndirectBranch = 1, rd = 0 in {
188255 // Long branches
189 def Bi : I16ri<0, (outs), (ins i16imm:$brdst),
190 "br\t$brdst",
191 [(brind tblockaddress:$brdst)]>;
192 def Br : I16rr<0, (outs), (ins GR16:$brdst),
193 "br\t$brdst",
194 [(brind GR16:$brdst)]>;
195 def Bm : I16rm<0, (outs), (ins memsrc:$brdst),
196 "br\t$brdst",
197 [(brind (load addr:$brdst))]>;
256 def Bi : I16ri<0b0100, (outs), (ins i16imm:$imm),
257 "br\t$imm",
258 [(brind tblockaddress:$imm)]>;
259 def Br : I16rr<0b0100, (outs), (ins GR16:$rs),
260 "br\t$rs",
261 [(brind GR16:$rs)]>;
262 def Bm : I16rm<0b0100, (outs), (ins memsrc:$src),
263 "br\t$src",
264 [(brind (load addr:$src))]>;
198265 }
199266 }
200267
201268 // Conditional branches
202269 let Uses = [SR] in
203 def JCC : CJForm<0, 0,
204 (outs), (ins jmptarget:$dst, cc:$cc),
205 "j$cc\t$dst",
206 [(MSP430brcc bb:$dst, imm:$cc)]>;
270 def JCC : CJForm<(outs), (ins jmptarget:$dst, cc:$cond),
271 "j$cond\t$dst",
272 [(MSP430brcc bb:$dst, imm:$cond)]>;
207273 } // isBranch, isTerminator
208274
209275 //===----------------------------------------------------------------------===//
210276 // Call Instructions...
211277 //
212 let isCall = 1 in
213 // All calls clobber the non-callee saved registers. SPW is marked as
214 // a use to prevent stack-pointer assignments that appear immediately
215 // before calls from potentially appearing dead. Uses for argument
216 // registers are added manually.
217 let Defs = [R11, R12, R13, R14, R15, SR],
218 Uses = [SP] in {
219 def CALLi : II16i<0x0,
220 (outs), (ins i16imm:$dst),
221 "call\t$dst", [(MSP430call imm:$dst)]>;
222 def CALLr : II16r<0x0,
223 (outs), (ins GR16:$dst),
224 "call\t$dst", [(MSP430call GR16:$dst)]>;
225 def CALLm : II16m<0x0,
226 (outs), (ins memsrc:$dst),
227 "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
228 }
229
278 // All calls clobber the non-callee saved registers. SPW is marked as
279 // a use to prevent stack-pointer assignments that appear immediately
280 // before calls from potentially appearing dead. Uses for argument
281 // registers are added manually.
282 let isCall = 1,
283 Defs = [R11, R12, R13, R14, R15, SR],
284 Uses = [SP] in {
285 def CALLi : II16i<0b101,
286 (outs), (ins i16imm:$imm),
287 "call\t$imm", [(MSP430call imm:$imm)]>;
288 def CALLr : II16r<0b101,
289 (outs), (ins GR16:$rs),
290 "call\t$rs", [(MSP430call GR16:$rs)]>;
291 def CALLm : II16m<0b101,
292 (outs), (ins memsrc:$src),
293 "call\t$src", [(MSP430call (load addr:$src))]>;
294 }
230295
231296 //===----------------------------------------------------------------------===//
232297 // Miscellaneous Instructions...
233298 //
234 let Defs = [SP], Uses = [SP], hasSideEffects=0 in {
299 let Defs = [SP], Uses = [SP], hasSideEffects = 0 in {
235300 let mayLoad = 1 in
236 def POP16r : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
237 (outs GR16:$reg), (ins), "pop.w\t$reg", []>;
301 def POP16r : IForm16<0b0100, DstReg, SrcPostInc, 2,
302 (outs GR16:$rd), (ins), "pop\t$rd", []> {
303 let DecoderNamespace = "Delta";
304 let rs = 1;
305 }
238306
239307 let mayStore = 1 in
240 def PUSH16r : II16r<0x0,
241 (outs), (ins GR16:$reg), "push.w\t$reg",[]>;
308 def PUSH8r : II8r<0b100, (outs), (ins GR8:$rs), "push.b\t$rs", []>;
309 def PUSH16r : II16r<0b100, (outs), (ins GR16:$rs), "push\t$rs", []>;
310 def PUSH16c : II16c<0b100, (outs), (ins cg16imm:$imm), "push\t$imm", []>;
311 def PUSH16i : II16i<0b100, (outs), (ins i16imm:$imm), "push\t$imm", []>;
242312 }
243313
244314 //===----------------------------------------------------------------------===//
246316
247317 // FIXME: Provide proper encoding!
248318 let hasSideEffects = 0 in {
249 def MOV8rr : I8rr<0x0,
250 (outs GR8:$dst), (ins GR8:$src),
251 "mov.b\t{$src, $dst}",
319 def MOV8rr : I8rr<0b0100,
320 (outs GR8:$rd), (ins GR8:$rs),
321 "mov.b\t{$rs, $rd}",
252322 []>;
253 def MOV16rr : I16rr<0x0,
254 (outs GR16:$dst), (ins GR16:$src),
255 "mov.w\t{$src, $dst}",
323 def MOV16rr : I16rr<0b0100,
324 (outs GR16:$rd), (ins GR16:$rs),
325 "mov\t{$rs, $rd}",
256326 []>;
257327 }
258328
259329 // FIXME: Provide proper encoding!
260330 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
261 def MOV8ri : I8ri<0x0,
262 (outs GR8:$dst), (ins i8imm:$src),
263 "mov.b\t{$src, $dst}",
264 [(set GR8:$dst, imm:$src)]>;
265 def MOV16ri : I16ri<0x0,
266 (outs GR16:$dst), (ins i16imm:$src),
267 "mov.w\t{$src, $dst}",
268 [(set GR16:$dst, imm:$src)]>;
331 def MOV8rc : I8rc<0b0100,
332 (outs GR8:$rd), (ins cg8imm:$imm),
333 "mov.b\t$imm, $rd",
334 [(set GR8:$rd, cg8imm:$imm)]>;
335 def MOV16rc : I16rc<0b0100,
336 (outs GR16:$rd), (ins cg16imm:$imm),
337 "mov\t$imm, $rd",
338 [(set GR16:$rd, cg16imm:$imm)]>;
339 def MOV8ri : I8ri<0b0100,
340 (outs GR8:$rd), (ins i8imm:$imm),
341 "mov.b\t{$imm, $rd}",
342 [(set GR8:$rd, imm:$imm)]>;
343 def MOV16ri : I16ri<0b0100,
344 (outs GR16:$rd), (ins i16imm:$imm),
345 "mov\t{$imm, $rd}",
346 [(set GR16:$rd, imm:$imm)]>;
269347 }
270348
271349 let canFoldAsLoad = 1, isReMaterializable = 1 in {
272 def MOV8rm : I8rm<0x0,
273 (outs GR8:$dst), (ins memsrc:$src),
274 "mov.b\t{$src, $dst}",
275 [(set GR8:$dst, (load addr:$src))]>;
276 def MOV16rm : I16rm<0x0,
277 (outs GR16:$dst), (ins memsrc:$src),
278 "mov.w\t{$src, $dst}",
279 [(set GR16:$dst, (load addr:$src))]>;
280 }
281
282 def MOVZX16rr8 : I8rr<0x0,
283 (outs GR16:$dst), (ins GR8:$src),
284 "mov.b\t{$src, $dst}",
285 [(set GR16:$dst, (zext GR8:$src))]>;
286 def MOVZX16rm8 : I8rm<0x0,
287 (outs GR16:$dst), (ins memsrc:$src),
288 "mov.b\t{$src, $dst}",
289 [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
290
291 let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
292 def MOV8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
293 (outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
294 "mov.b\t{@$base+, $dst}", []>;
295 def MOV16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
296 (outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
297 "mov.w\t{@$base+, $dst}", []>;
350 def MOV8rm : I8rm<0b0100,
351 (outs GR8:$rd), (ins memsrc:$src),
352 "mov.b\t{$src, $rd}",
353 [(set GR8:$rd, (load addr:$src))]>;
354 def MOV16rm : I16rm<0b0100,
355 (outs GR16:$rd), (ins memsrc:$src),
356 "mov\t{$src, $rd}",
357 [(set GR16:$rd, (load addr:$src))]>;
358 def MOV8rn : I8rn<0b0100,
359 (outs GR8:$rd), (ins indreg:$rs),
360 "mov.b\t{$rs, $rd}",
361 [(set GR8:$rd, (load addr:$rs))]>;
362 def MOV16rn : I16rn<0b0100,
363 (outs GR16:$rd), (ins indreg:$rs),
364 "mov\t{$rs, $rd}",
365 [(set GR16:$rd, (load addr:$rs))]>;
366 }
367
368 let isCodeGenOnly = 1 in {
369 def MOVZX16rr8 : I8rr<0b0100,
370 (outs GR16:$rd), (ins GR8:$rs),
371 "mov.b\t{$rs, $rd}",
372 [(set GR16:$rd, (zext GR8:$rs))]>;
373 def MOVZX16rm8 : I8rm<0b0100,
374 (outs GR16:$rd), (ins memsrc:$src),
375 "mov.b\t{$src, $rd}",
376 [(set GR16:$rd, (zextloadi16i8 addr:$src))]>;
377 }
378
379 let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$rs = $wb" in {
380 def MOV8rp : I8rp<0b0100,
381 (outs GR8:$rd, GR16:$wb), (ins postreg:$rs),
382 "mov.b\t{$rs, $rd}", []>;
383 def MOV16rp : I16rp<0b0100,
384 (outs GR16:$rd, GR16:$wb), (ins postreg:$rs),
385 "mov\t{$rs, $rd}", []>;
298386 }
299387
300388 // Any instruction that defines a 8-bit result leaves the high half of the
312400 def : Pat<(i16 (zext def8:$src)),
313401 (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
314402
315 def MOV8mi : I8mi<0x0,
316 (outs), (ins memdst:$dst, i8imm:$src),
317 "mov.b\t{$src, $dst}",
318 [(store (i8 imm:$src), addr:$dst)]>;
319 def MOV16mi : I16mi<0x0,
320 (outs), (ins memdst:$dst, i16imm:$src),
321 "mov.w\t{$src, $dst}",
322 [(store (i16 imm:$src), addr:$dst)]>;
323
324 def MOV8mr : I8mr<0x0,
325 (outs), (ins memdst:$dst, GR8:$src),
326 "mov.b\t{$src, $dst}",
327 [(store GR8:$src, addr:$dst)]>;
328 def MOV16mr : I16mr<0x0,
329 (outs), (ins memdst:$dst, GR16:$src),
330 "mov.w\t{$src, $dst}",
331 [(store GR16:$src, addr:$dst)]>;
332
333 def MOV8mm : I8mm<0x0,
403 def MOV8mc : I8mc<0b0100,
404 (outs), (ins memdst:$dst, cg8imm:$imm),
405 "mov.b\t{$imm, $dst}",
406 [(store (i8 cg8imm:$imm), addr:$dst)]>;
407 def MOV16mc : I16mc<0b0100,
408 (outs), (ins memdst:$dst, cg16imm:$imm),
409 "mov\t{$imm, $dst}",
410 [(store (i16 cg16imm:$imm), addr:$dst)]>;
411
412 def MOV8mi : I8mi<0b0100,
413 (outs), (ins memdst:$dst, i8imm:$imm),
414 "mov.b\t{$imm, $dst}",
415 [(store (i8 imm:$imm), addr:$dst)]>;
416 def MOV16mi : I16mi<0b0100,
417 (outs), (ins memdst:$dst, i16imm:$imm),
418 "mov\t{$imm, $dst}",
419 [(store (i16 imm:$imm), addr:$dst)]>;
420
421 def MOV8mr : I8mr<0b0100,
422 (outs), (ins memdst:$dst, GR8:$rs),
423 "mov.b\t{$rs, $dst}",
424 [(store GR8:$rs, addr:$dst)]>;
425 def MOV16mr : I16mr<0b0100,
426 (outs), (ins memdst:$dst, GR16:$rs),
427 "mov\t{$rs, $dst}",
428 [(store GR16:$rs, addr:$dst)]>;
429
430 def MOV8mm : I8mm<0b0100,
334431 (outs), (ins memdst:$dst, memsrc:$src),
335432 "mov.b\t{$src, $dst}",
336433 [(store (i8 (load addr:$src)), addr:$dst)]>;
337 def MOV16mm : I16mm<0x0,
434 def MOV16mm : I16mm<0b0100,
338435 (outs), (ins memdst:$dst, memsrc:$src),
339 "mov.w\t{$src, $dst}",
436 "mov\t{$src, $dst}",
340437 [(store (i16 (load addr:$src)), addr:$dst)]>;
341438
342439 //===----------------------------------------------------------------------===//
343440 // Arithmetic Instructions
344441
345 let Constraints = "$src = $dst" in {
442 multiclass Arith opcode, string asmstring, SDNode node,
443 bit commutes, list uses> {
444 let Defs = [SR], Uses = uses in {
445 let Constraints = "$src2 = $rd" in {
446 let isCommutable = commutes in {
447 def 8rr : I8rr
448 !strconcat(asmstring, ".b\t$rs, $rd"),
449 [(set GR8:$rd, (node GR8:$src2, GR8:$rs)),
450 (implicit SR)]>;
451 def 16rr : I16rr
452 !strconcat(asmstring, "\t$rs, $rd"),
453 [(set GR16:$rd, (node GR16:$src2, GR16:$rs)),
454 (implicit SR)]>;
455 }
456 def 8rm : I8rm
457 !strconcat(asmstring, ".b\t$src, $rd"),
458 [(set GR8:$rd, (node GR8:$src2, (load addr:$src))),
459 (implicit SR)]>;
460 def 16rm : I16rm
461 !strconcat(asmstring, "\t$src, $rd"),
462 [(set GR16:$rd, (node GR16:$src2, (load addr:$src))),
463 (implicit SR)]>;
464 def 8rn : I8rn
465 !strconcat(asmstring, ".b\t$rs, $rd"), []>;
466 def 16rn : I16rn
467 !strconcat(asmstring, "\t$rs, $rd"), []>;
468 let mayLoad = 1,
469 hasExtraDefRegAllocReq = 1,
470 Constraints = "$rs = $wb, $src2 = $rd" in {
471 def 8rp : I8rp
472 !strconcat(asmstring, ".b\t$rs, $rd"), []>;
473 def 16rp : I16rp
474 !strconcat(asmstring, "\t$rs, $rd"), []>;
475 }
476 def 8rc : I8rc
477 !strconcat(asmstring, ".b\t$imm, $rd"),
478 [(set GR8:$rd, (node GR8:$src2, cg8imm:$imm)),
479 (implicit SR)]>;
480 def 16rc : I16rc
481 !strconcat(asmstring, "\t$imm, $rd"),
482 [(set GR16:$rd, (node GR16:$src2, cg16imm:$imm)),
483 (implicit SR)]>;
484 def 8ri : I8ri
485 !strconcat(asmstring, ".b\t$imm, $rd"),
486 [(set GR8:$rd, (node GR8:$src2, imm:$imm)),
487 (implicit SR)]>;
488 def 16ri : I16ri
489 !strconcat(asmstring, "\t$imm, $rd"),
490 [(set GR16:$rd, (node GR16:$src2, imm:$imm)),
491 (implicit SR)]>;
492 }
493 def 8mr : I8mr
494 !strconcat(asmstring, ".b\t$rs, $dst"),
495 [(store (node (load addr:$dst), GR8:$rs), addr:$dst),
496 (implicit SR)]>;
497 def 16mr : I16mr
498 !strconcat(asmstring, "\t$rs, $dst"),
499 [(store (node (load addr:$dst), GR16:$rs), addr:$dst),
500 (implicit SR)]>;
501 def 8mc : I8mc
502 !strconcat(asmstring, ".b\t$imm, $dst"),
503 [(store (node (load addr:$dst), (i8 cg8imm:$imm)), addr:$dst),
504 (implicit SR)]>;
505 def 16mc : I16mc
506 !strconcat(asmstring, "\t$imm, $dst"),
507 [(store (node (load addr:$dst), (i16 cg16imm:$imm)), addr:$dst),
508 (implicit SR)]>;
509 def 8mi : I8mi
510 !strconcat(asmstring, ".b\t$imm, $dst"),
511