Use BranchProbability instead of floating points in IfConverter.
[llvm/stm8.git] / lib / Target / ARM / AsmParser / ARMAsmParser.cpp
blobd8fd809c4b084d6ef6325cf880146cc957407728
1 //===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "ARM.h"
11 #include "ARMAddressingModes.h"
12 #include "ARMMCExpr.h"
13 #include "ARMBaseRegisterInfo.h"
14 #include "ARMSubtarget.h"
15 #include "llvm/MC/MCParser/MCAsmLexer.h"
16 #include "llvm/MC/MCParser/MCAsmParser.h"
17 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/Target/TargetRegistry.h"
25 #include "llvm/Target/TargetAsmParser.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "llvm/ADT/OwningPtr.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/StringExtras.h"
31 #include "llvm/ADT/StringSwitch.h"
32 #include "llvm/ADT/Twine.h"
34 #define GET_SUBTARGETINFO_ENUM
35 #include "ARMGenSubtargetInfo.inc"
37 using namespace llvm;
39 namespace {
41 class ARMOperand;
43 class ARMAsmParser : public TargetAsmParser {
44 MCSubtargetInfo &STI;
45 MCAsmParser &Parser;
47 MCAsmParser &getParser() const { return Parser; }
48 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
50 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
51 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
53 int TryParseRegister();
54 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
55 bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
56 bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
57 bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
58 bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
59 ARMII::AddrMode AddrMode);
60 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
61 bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
62 const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
63 MCSymbolRefExpr::VariantKind Variant);
66 bool ParseMemoryOffsetReg(bool &Negative,
67 bool &OffsetRegShifted,
68 enum ARM_AM::ShiftOpc &ShiftType,
69 const MCExpr *&ShiftAmount,
70 const MCExpr *&Offset,
71 bool &OffsetIsReg,
72 int &OffsetRegNum,
73 SMLoc &E);
74 bool ParseShift(enum ARM_AM::ShiftOpc &St,
75 const MCExpr *&ShiftAmount, SMLoc &E);
76 bool ParseDirectiveWord(unsigned Size, SMLoc L);
77 bool ParseDirectiveThumb(SMLoc L);
78 bool ParseDirectiveThumbFunc(SMLoc L);
79 bool ParseDirectiveCode(SMLoc L);
80 bool ParseDirectiveSyntax(SMLoc L);
82 bool MatchAndEmitInstruction(SMLoc IDLoc,
83 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
84 MCStreamer &Out);
85 void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
86 bool &CanAcceptPredicationCode);
88 bool isThumb() const {
89 // FIXME: Can tablegen auto-generate this?
90 return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
92 bool isThumbOne() const {
93 return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
95 void SwitchMode() {
96 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
97 setAvailableFeatures(FB);
100 /// @name Auto-generated Match Functions
101 /// {
103 #define GET_ASSEMBLER_HEADER
104 #include "ARMGenAsmMatcher.inc"
106 /// }
108 OperandMatchResultTy tryParseCoprocNumOperand(
109 SmallVectorImpl<MCParsedAsmOperand*>&);
110 OperandMatchResultTy tryParseCoprocRegOperand(
111 SmallVectorImpl<MCParsedAsmOperand*>&);
112 OperandMatchResultTy tryParseMemBarrierOptOperand(
113 SmallVectorImpl<MCParsedAsmOperand*>&);
114 OperandMatchResultTy tryParseProcIFlagsOperand(
115 SmallVectorImpl<MCParsedAsmOperand*>&);
116 OperandMatchResultTy tryParseMSRMaskOperand(
117 SmallVectorImpl<MCParsedAsmOperand*>&);
118 OperandMatchResultTy tryParseMemMode2Operand(
119 SmallVectorImpl<MCParsedAsmOperand*>&);
120 OperandMatchResultTy tryParseMemMode3Operand(
121 SmallVectorImpl<MCParsedAsmOperand*>&);
123 // Asm Match Converter Methods
124 bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
125 const SmallVectorImpl<MCParsedAsmOperand*> &);
126 bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
127 const SmallVectorImpl<MCParsedAsmOperand*> &);
128 bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
129 const SmallVectorImpl<MCParsedAsmOperand*> &);
130 bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
131 const SmallVectorImpl<MCParsedAsmOperand*> &);
133 public:
134 ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
135 : TargetAsmParser(), STI(_STI), Parser(_Parser) {
136 MCAsmParserExtension::Initialize(_Parser);
138 // Initialize the set of available features.
139 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
142 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
143 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
144 virtual bool ParseDirective(AsmToken DirectiveID);
146 } // end anonymous namespace
148 namespace {
150 /// ARMOperand - Instances of this class represent a parsed ARM machine
151 /// instruction.
152 class ARMOperand : public MCParsedAsmOperand {
153 enum KindTy {
154 CondCode,
155 CCOut,
156 CoprocNum,
157 CoprocReg,
158 Immediate,
159 MemBarrierOpt,
160 Memory,
161 MSRMask,
162 ProcIFlags,
163 Register,
164 RegisterList,
165 DPRRegisterList,
166 SPRRegisterList,
167 Shifter,
168 Token
169 } Kind;
171 SMLoc StartLoc, EndLoc;
172 SmallVector<unsigned, 8> Registers;
174 union {
175 struct {
176 ARMCC::CondCodes Val;
177 } CC;
179 struct {
180 ARM_MB::MemBOpt Val;
181 } MBOpt;
183 struct {
184 unsigned Val;
185 } Cop;
187 struct {
188 ARM_PROC::IFlags Val;
189 } IFlags;
191 struct {
192 unsigned Val;
193 } MMask;
195 struct {
196 const char *Data;
197 unsigned Length;
198 } Tok;
200 struct {
201 unsigned RegNum;
202 } Reg;
204 struct {
205 const MCExpr *Val;
206 } Imm;
208 /// Combined record for all forms of ARM address expressions.
209 struct {
210 ARMII::AddrMode AddrMode;
211 unsigned BaseRegNum;
212 union {
213 unsigned RegNum; ///< Offset register num, when OffsetIsReg.
214 const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
215 } Offset;
216 const MCExpr *ShiftAmount; // used when OffsetRegShifted is true
217 enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
218 unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
219 unsigned Preindexed : 1;
220 unsigned Postindexed : 1;
221 unsigned OffsetIsReg : 1;
222 unsigned Negative : 1; // only used when OffsetIsReg is true
223 unsigned Writeback : 1;
224 } Mem;
226 struct {
227 ARM_AM::ShiftOpc ShiftTy;
228 unsigned RegNum;
229 } Shift;
232 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
233 public:
234 ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
235 Kind = o.Kind;
236 StartLoc = o.StartLoc;
237 EndLoc = o.EndLoc;
238 switch (Kind) {
239 case CondCode:
240 CC = o.CC;
241 break;
242 case Token:
243 Tok = o.Tok;
244 break;
245 case CCOut:
246 case Register:
247 Reg = o.Reg;
248 break;
249 case RegisterList:
250 case DPRRegisterList:
251 case SPRRegisterList:
252 Registers = o.Registers;
253 break;
254 case CoprocNum:
255 case CoprocReg:
256 Cop = o.Cop;
257 break;
258 case Immediate:
259 Imm = o.Imm;
260 break;
261 case MemBarrierOpt:
262 MBOpt = o.MBOpt;
263 break;
264 case Memory:
265 Mem = o.Mem;
266 break;
267 case MSRMask:
268 MMask = o.MMask;
269 break;
270 case ProcIFlags:
271 IFlags = o.IFlags;
272 break;
273 case Shifter:
274 Shift = o.Shift;
275 break;
279 /// getStartLoc - Get the location of the first token of this operand.
280 SMLoc getStartLoc() const { return StartLoc; }
281 /// getEndLoc - Get the location of the last token of this operand.
282 SMLoc getEndLoc() const { return EndLoc; }
284 ARMCC::CondCodes getCondCode() const {
285 assert(Kind == CondCode && "Invalid access!");
286 return CC.Val;
289 unsigned getCoproc() const {
290 assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
291 return Cop.Val;
294 StringRef getToken() const {
295 assert(Kind == Token && "Invalid access!");
296 return StringRef(Tok.Data, Tok.Length);
299 unsigned getReg() const {
300 assert((Kind == Register || Kind == CCOut) && "Invalid access!");
301 return Reg.RegNum;
304 const SmallVectorImpl<unsigned> &getRegList() const {
305 assert((Kind == RegisterList || Kind == DPRRegisterList ||
306 Kind == SPRRegisterList) && "Invalid access!");
307 return Registers;
310 const MCExpr *getImm() const {
311 assert(Kind == Immediate && "Invalid access!");
312 return Imm.Val;
315 ARM_MB::MemBOpt getMemBarrierOpt() const {
316 assert(Kind == MemBarrierOpt && "Invalid access!");
317 return MBOpt.Val;
320 ARM_PROC::IFlags getProcIFlags() const {
321 assert(Kind == ProcIFlags && "Invalid access!");
322 return IFlags.Val;
325 unsigned getMSRMask() const {
326 assert(Kind == MSRMask && "Invalid access!");
327 return MMask.Val;
330 /// @name Memory Operand Accessors
331 /// @{
332 ARMII::AddrMode getMemAddrMode() const {
333 return Mem.AddrMode;
335 unsigned getMemBaseRegNum() const {
336 return Mem.BaseRegNum;
338 unsigned getMemOffsetRegNum() const {
339 assert(Mem.OffsetIsReg && "Invalid access!");
340 return Mem.Offset.RegNum;
342 const MCExpr *getMemOffset() const {
343 assert(!Mem.OffsetIsReg && "Invalid access!");
344 return Mem.Offset.Value;
346 unsigned getMemOffsetRegShifted() const {
347 assert(Mem.OffsetIsReg && "Invalid access!");
348 return Mem.OffsetRegShifted;
350 const MCExpr *getMemShiftAmount() const {
351 assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
352 return Mem.ShiftAmount;
354 enum ARM_AM::ShiftOpc getMemShiftType() const {
355 assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
356 return Mem.ShiftType;
358 bool getMemPreindexed() const { return Mem.Preindexed; }
359 bool getMemPostindexed() const { return Mem.Postindexed; }
360 bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
361 bool getMemNegative() const { return Mem.Negative; }
362 bool getMemWriteback() const { return Mem.Writeback; }
364 /// @}
366 bool isCoprocNum() const { return Kind == CoprocNum; }
367 bool isCoprocReg() const { return Kind == CoprocReg; }
368 bool isCondCode() const { return Kind == CondCode; }
369 bool isCCOut() const { return Kind == CCOut; }
370 bool isImm() const { return Kind == Immediate; }
371 bool isImm0_255() const {
372 if (Kind != Immediate)
373 return false;
374 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
375 if (!CE) return false;
376 int64_t Value = CE->getValue();
377 return Value >= 0 && Value < 256;
379 bool isT2SOImm() const {
380 if (Kind != Immediate)
381 return false;
382 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
383 if (!CE) return false;
384 int64_t Value = CE->getValue();
385 return ARM_AM::getT2SOImmVal(Value) != -1;
387 bool isReg() const { return Kind == Register; }
388 bool isRegList() const { return Kind == RegisterList; }
389 bool isDPRRegList() const { return Kind == DPRRegisterList; }
390 bool isSPRRegList() const { return Kind == SPRRegisterList; }
391 bool isToken() const { return Kind == Token; }
392 bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
393 bool isMemory() const { return Kind == Memory; }
394 bool isShifter() const { return Kind == Shifter; }
395 bool isMemMode2() const {
396 if (getMemAddrMode() != ARMII::AddrMode2)
397 return false;
399 if (getMemOffsetIsReg())
400 return true;
402 if (getMemNegative() &&
403 !(getMemPostindexed() || getMemPreindexed()))
404 return false;
406 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
407 if (!CE) return false;
408 int64_t Value = CE->getValue();
410 // The offset must be in the range 0-4095 (imm12).
411 if (Value > 4095 || Value < -4095)
412 return false;
414 return true;
416 bool isMemMode3() const {
417 if (getMemAddrMode() != ARMII::AddrMode3)
418 return false;
420 if (getMemOffsetIsReg()) {
421 if (getMemOffsetRegShifted())
422 return false; // No shift with offset reg allowed
423 return true;
426 if (getMemNegative() &&
427 !(getMemPostindexed() || getMemPreindexed()))
428 return false;
430 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
431 if (!CE) return false;
432 int64_t Value = CE->getValue();
434 // The offset must be in the range 0-255 (imm8).
435 if (Value > 255 || Value < -255)
436 return false;
438 return true;
440 bool isMemMode5() const {
441 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
442 getMemNegative())
443 return false;
445 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
446 if (!CE) return false;
448 // The offset must be a multiple of 4 in the range 0-1020.
449 int64_t Value = CE->getValue();
450 return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
452 bool isMemMode7() const {
453 if (!isMemory() ||
454 getMemPreindexed() ||
455 getMemPostindexed() ||
456 getMemOffsetIsReg() ||
457 getMemNegative() ||
458 getMemWriteback())
459 return false;
461 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
462 if (!CE) return false;
464 if (CE->getValue())
465 return false;
467 return true;
469 bool isMemModeRegThumb() const {
470 if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
471 return false;
472 return true;
474 bool isMemModeImmThumb() const {
475 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
476 return false;
478 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
479 if (!CE) return false;
481 // The offset must be a multiple of 4 in the range 0-124.
482 uint64_t Value = CE->getValue();
483 return ((Value & 0x3) == 0 && Value <= 124);
485 bool isMSRMask() const { return Kind == MSRMask; }
486 bool isProcIFlags() const { return Kind == ProcIFlags; }
488 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
489 // Add as immediates when possible. Null MCExpr = 0.
490 if (Expr == 0)
491 Inst.addOperand(MCOperand::CreateImm(0));
492 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
493 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
494 else
495 Inst.addOperand(MCOperand::CreateExpr(Expr));
498 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
499 assert(N == 2 && "Invalid number of operands!");
500 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
501 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
502 Inst.addOperand(MCOperand::CreateReg(RegNum));
505 void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
506 assert(N == 1 && "Invalid number of operands!");
507 Inst.addOperand(MCOperand::CreateImm(getCoproc()));
510 void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
511 assert(N == 1 && "Invalid number of operands!");
512 Inst.addOperand(MCOperand::CreateImm(getCoproc()));
515 void addCCOutOperands(MCInst &Inst, unsigned N) const {
516 assert(N == 1 && "Invalid number of operands!");
517 Inst.addOperand(MCOperand::CreateReg(getReg()));
520 void addRegOperands(MCInst &Inst, unsigned N) const {
521 assert(N == 1 && "Invalid number of operands!");
522 Inst.addOperand(MCOperand::CreateReg(getReg()));
525 void addShifterOperands(MCInst &Inst, unsigned N) const {
526 assert(N == 1 && "Invalid number of operands!");
527 Inst.addOperand(MCOperand::CreateImm(
528 ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
531 void addRegListOperands(MCInst &Inst, unsigned N) const {
532 assert(N == 1 && "Invalid number of operands!");
533 const SmallVectorImpl<unsigned> &RegList = getRegList();
534 for (SmallVectorImpl<unsigned>::const_iterator
535 I = RegList.begin(), E = RegList.end(); I != E; ++I)
536 Inst.addOperand(MCOperand::CreateReg(*I));
539 void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
540 addRegListOperands(Inst, N);
543 void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
544 addRegListOperands(Inst, N);
547 void addImmOperands(MCInst &Inst, unsigned N) const {
548 assert(N == 1 && "Invalid number of operands!");
549 addExpr(Inst, getImm());
552 void addImm0_255Operands(MCInst &Inst, unsigned N) const {
553 assert(N == 1 && "Invalid number of operands!");
554 addExpr(Inst, getImm());
557 void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
558 assert(N == 1 && "Invalid number of operands!");
559 addExpr(Inst, getImm());
562 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
563 assert(N == 1 && "Invalid number of operands!");
564 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
567 void addMemMode7Operands(MCInst &Inst, unsigned N) const {
568 assert(N == 1 && isMemMode7() && "Invalid number of operands!");
569 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
571 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
572 (void)CE;
573 assert((CE || CE->getValue() == 0) &&
574 "No offset operand support in mode 7");
577 void addMemMode2Operands(MCInst &Inst, unsigned N) const {
578 assert(isMemMode2() && "Invalid mode or number of operands!");
579 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
580 unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
582 if (getMemOffsetIsReg()) {
583 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
585 ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
586 ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
587 int64_t ShiftAmount = 0;
589 if (getMemOffsetRegShifted()) {
590 ShOpc = getMemShiftType();
591 const MCConstantExpr *CE =
592 dyn_cast<MCConstantExpr>(getMemShiftAmount());
593 ShiftAmount = CE->getValue();
596 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
597 ShOpc, IdxMode)));
598 return;
601 // Create a operand placeholder to always yield the same number of operands.
602 Inst.addOperand(MCOperand::CreateReg(0));
604 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
605 // the difference?
606 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
607 assert(CE && "Non-constant mode 2 offset operand!");
608 int64_t Offset = CE->getValue();
610 if (Offset >= 0)
611 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
612 Offset, ARM_AM::no_shift, IdxMode)));
613 else
614 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
615 -Offset, ARM_AM::no_shift, IdxMode)));
618 void addMemMode3Operands(MCInst &Inst, unsigned N) const {
619 assert(isMemMode3() && "Invalid mode or number of operands!");
620 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
621 unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
623 if (getMemOffsetIsReg()) {
624 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
626 ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
627 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
628 IdxMode)));
629 return;
632 // Create a operand placeholder to always yield the same number of operands.
633 Inst.addOperand(MCOperand::CreateReg(0));
635 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
636 // the difference?
637 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
638 assert(CE && "Non-constant mode 3 offset operand!");
639 int64_t Offset = CE->getValue();
641 if (Offset >= 0)
642 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
643 Offset, IdxMode)));
644 else
645 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
646 -Offset, IdxMode)));
649 void addMemMode5Operands(MCInst &Inst, unsigned N) const {
650 assert(N == 2 && isMemMode5() && "Invalid number of operands!");
652 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
653 assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
655 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
656 // the difference?
657 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
658 assert(CE && "Non-constant mode 5 offset operand!");
660 // The MCInst offset operand doesn't include the low two bits (like
661 // the instruction encoding).
662 int64_t Offset = CE->getValue() / 4;
663 if (Offset >= 0)
664 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
665 Offset)));
666 else
667 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
668 -Offset)));
671 void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
672 assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
673 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
674 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
677 void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
678 assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
679 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
680 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
681 assert(CE && "Non-constant mode offset operand!");
682 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
685 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 1 && "Invalid number of operands!");
687 Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
690 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
691 assert(N == 1 && "Invalid number of operands!");
692 Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
695 virtual void dump(raw_ostream &OS) const;
697 static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
698 ARMOperand *Op = new ARMOperand(CondCode);
699 Op->CC.Val = CC;
700 Op->StartLoc = S;
701 Op->EndLoc = S;
702 return Op;
705 static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
706 ARMOperand *Op = new ARMOperand(CoprocNum);
707 Op->Cop.Val = CopVal;
708 Op->StartLoc = S;
709 Op->EndLoc = S;
710 return Op;
713 static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
714 ARMOperand *Op = new ARMOperand(CoprocReg);
715 Op->Cop.Val = CopVal;
716 Op->StartLoc = S;
717 Op->EndLoc = S;
718 return Op;
721 static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
722 ARMOperand *Op = new ARMOperand(CCOut);
723 Op->Reg.RegNum = RegNum;
724 Op->StartLoc = S;
725 Op->EndLoc = S;
726 return Op;
729 static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
730 ARMOperand *Op = new ARMOperand(Token);
731 Op->Tok.Data = Str.data();
732 Op->Tok.Length = Str.size();
733 Op->StartLoc = S;
734 Op->EndLoc = S;
735 return Op;
738 static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
739 ARMOperand *Op = new ARMOperand(Register);
740 Op->Reg.RegNum = RegNum;
741 Op->StartLoc = S;
742 Op->EndLoc = E;
743 return Op;
746 static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
747 SMLoc S, SMLoc E) {
748 ARMOperand *Op = new ARMOperand(Shifter);
749 Op->Shift.ShiftTy = ShTy;
750 Op->StartLoc = S;
751 Op->EndLoc = E;
752 return Op;
755 static ARMOperand *
756 CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
757 SMLoc StartLoc, SMLoc EndLoc) {
758 KindTy Kind = RegisterList;
760 if (ARM::DPRRegClass.contains(Regs.front().first))
761 Kind = DPRRegisterList;
762 else if (ARM::SPRRegClass.contains(Regs.front().first))
763 Kind = SPRRegisterList;
765 ARMOperand *Op = new ARMOperand(Kind);
766 for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
767 I = Regs.begin(), E = Regs.end(); I != E; ++I)
768 Op->Registers.push_back(I->first);
769 array_pod_sort(Op->Registers.begin(), Op->Registers.end());
770 Op->StartLoc = StartLoc;
771 Op->EndLoc = EndLoc;
772 return Op;
775 static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
776 ARMOperand *Op = new ARMOperand(Immediate);
777 Op->Imm.Val = Val;
778 Op->StartLoc = S;
779 Op->EndLoc = E;
780 return Op;
783 static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
784 bool OffsetIsReg, const MCExpr *Offset,
785 int OffsetRegNum, bool OffsetRegShifted,
786 enum ARM_AM::ShiftOpc ShiftType,
787 const MCExpr *ShiftAmount, bool Preindexed,
788 bool Postindexed, bool Negative, bool Writeback,
789 SMLoc S, SMLoc E) {
790 assert((OffsetRegNum == -1 || OffsetIsReg) &&
791 "OffsetRegNum must imply OffsetIsReg!");
792 assert((!OffsetRegShifted || OffsetIsReg) &&
793 "OffsetRegShifted must imply OffsetIsReg!");
794 assert((Offset || OffsetIsReg) &&
795 "Offset must exists unless register offset is used!");
796 assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
797 "Cannot have shift amount without shifted register offset!");
798 assert((!Offset || !OffsetIsReg) &&
799 "Cannot have expression offset and register offset!");
801 ARMOperand *Op = new ARMOperand(Memory);
802 Op->Mem.AddrMode = AddrMode;
803 Op->Mem.BaseRegNum = BaseRegNum;
804 Op->Mem.OffsetIsReg = OffsetIsReg;
805 if (OffsetIsReg)
806 Op->Mem.Offset.RegNum = OffsetRegNum;
807 else
808 Op->Mem.Offset.Value = Offset;
809 Op->Mem.OffsetRegShifted = OffsetRegShifted;
810 Op->Mem.ShiftType = ShiftType;
811 Op->Mem.ShiftAmount = ShiftAmount;
812 Op->Mem.Preindexed = Preindexed;
813 Op->Mem.Postindexed = Postindexed;
814 Op->Mem.Negative = Negative;
815 Op->Mem.Writeback = Writeback;
817 Op->StartLoc = S;
818 Op->EndLoc = E;
819 return Op;
822 static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
823 ARMOperand *Op = new ARMOperand(MemBarrierOpt);
824 Op->MBOpt.Val = Opt;
825 Op->StartLoc = S;
826 Op->EndLoc = S;
827 return Op;
830 static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
831 ARMOperand *Op = new ARMOperand(ProcIFlags);
832 Op->IFlags.Val = IFlags;
833 Op->StartLoc = S;
834 Op->EndLoc = S;
835 return Op;
838 static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
839 ARMOperand *Op = new ARMOperand(MSRMask);
840 Op->MMask.Val = MMask;
841 Op->StartLoc = S;
842 Op->EndLoc = S;
843 return Op;
847 } // end anonymous namespace.
849 void ARMOperand::dump(raw_ostream &OS) const {
850 switch (Kind) {
851 case CondCode:
852 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
853 break;
854 case CCOut:
855 OS << "<ccout " << getReg() << ">";
856 break;
857 case CoprocNum:
858 OS << "<coprocessor number: " << getCoproc() << ">";
859 break;
860 case CoprocReg:
861 OS << "<coprocessor register: " << getCoproc() << ">";
862 break;
863 case MSRMask:
864 OS << "<mask: " << getMSRMask() << ">";
865 break;
866 case Immediate:
867 getImm()->print(OS);
868 break;
869 case MemBarrierOpt:
870 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
871 break;
872 case Memory:
873 OS << "<memory "
874 << "am:" << ARMII::AddrModeToString(getMemAddrMode())
875 << " base:" << getMemBaseRegNum();
876 if (getMemOffsetIsReg()) {
877 OS << " offset:<register " << getMemOffsetRegNum();
878 if (getMemOffsetRegShifted()) {
879 OS << " offset-shift-type:" << getMemShiftType();
880 OS << " offset-shift-amount:" << *getMemShiftAmount();
882 } else {
883 OS << " offset:" << *getMemOffset();
885 if (getMemOffsetIsReg())
886 OS << " (offset-is-reg)";
887 if (getMemPreindexed())
888 OS << " (pre-indexed)";
889 if (getMemPostindexed())
890 OS << " (post-indexed)";
891 if (getMemNegative())
892 OS << " (negative)";
893 if (getMemWriteback())
894 OS << " (writeback)";
895 OS << ">";
896 break;
897 case ProcIFlags: {
898 OS << "<ARM_PROC::";
899 unsigned IFlags = getProcIFlags();
900 for (int i=2; i >= 0; --i)
901 if (IFlags & (1 << i))
902 OS << ARM_PROC::IFlagsToString(1 << i);
903 OS << ">";
904 break;
906 case Register:
907 OS << "<register " << getReg() << ">";
908 break;
909 case Shifter:
910 OS << "<shifter " << getShiftOpcStr(Shift.ShiftTy) << ">";
911 break;
912 case RegisterList:
913 case DPRRegisterList:
914 case SPRRegisterList: {
915 OS << "<register_list ";
917 const SmallVectorImpl<unsigned> &RegList = getRegList();
918 for (SmallVectorImpl<unsigned>::const_iterator
919 I = RegList.begin(), E = RegList.end(); I != E; ) {
920 OS << *I;
921 if (++I < E) OS << ", ";
924 OS << ">";
925 break;
927 case Token:
928 OS << "'" << getToken() << "'";
929 break;
933 /// @name Auto-generated Match Functions
934 /// {
936 static unsigned MatchRegisterName(StringRef Name);
938 /// }
940 bool ARMAsmParser::ParseRegister(unsigned &RegNo,
941 SMLoc &StartLoc, SMLoc &EndLoc) {
942 RegNo = TryParseRegister();
944 return (RegNo == (unsigned)-1);
947 /// Try to parse a register name. The token must be an Identifier when called,
948 /// and if it is a register name the token is eaten and the register number is
949 /// returned. Otherwise return -1.
951 int ARMAsmParser::TryParseRegister() {
952 const AsmToken &Tok = Parser.getTok();
953 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
955 // FIXME: Validate register for the current architecture; we have to do
956 // validation later, so maybe there is no need for this here.
957 std::string upperCase = Tok.getString().str();
958 std::string lowerCase = LowercaseString(upperCase);
959 unsigned RegNum = MatchRegisterName(lowerCase);
960 if (!RegNum) {
961 RegNum = StringSwitch<unsigned>(lowerCase)
962 .Case("r13", ARM::SP)
963 .Case("r14", ARM::LR)
964 .Case("r15", ARM::PC)
965 .Case("ip", ARM::R12)
966 .Default(0);
968 if (!RegNum) return -1;
970 Parser.Lex(); // Eat identifier token.
971 return RegNum;
974 /// Try to parse a register name. The token must be an Identifier when called,
975 /// and if it is a register name the token is eaten and the register number is
976 /// returned. Otherwise return -1.
978 bool ARMAsmParser::TryParseShiftRegister(
979 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
980 SMLoc S = Parser.getTok().getLoc();
981 const AsmToken &Tok = Parser.getTok();
982 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
984 std::string upperCase = Tok.getString().str();
985 std::string lowerCase = LowercaseString(upperCase);
986 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
987 .Case("lsl", ARM_AM::lsl)
988 .Case("lsr", ARM_AM::lsr)
989 .Case("asr", ARM_AM::asr)
990 .Case("ror", ARM_AM::ror)
991 .Case("rrx", ARM_AM::rrx)
992 .Default(ARM_AM::no_shift);
994 if (ShiftTy == ARM_AM::no_shift)
995 return true;
997 Parser.Lex(); // Eat shift-type operand;
998 int RegNum = TryParseRegister();
999 if (RegNum == -1)
1000 return Error(Parser.getTok().getLoc(), "register expected");
1002 Operands.push_back(ARMOperand::CreateReg(RegNum,S, Parser.getTok().getLoc()));
1003 Operands.push_back(ARMOperand::CreateShifter(ShiftTy,
1004 S, Parser.getTok().getLoc()));
1006 return false;
1010 /// Try to parse a register name. The token must be an Identifier when called.
1011 /// If it's a register, an AsmOperand is created. Another AsmOperand is created
1012 /// if there is a "writeback". 'true' if it's not a register.
1014 /// TODO this is likely to change to allow different register types and or to
1015 /// parse for a specific register type.
1016 bool ARMAsmParser::
1017 TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1018 SMLoc S = Parser.getTok().getLoc();
1019 int RegNo = TryParseRegister();
1020 if (RegNo == -1)
1021 return true;
1023 Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1025 const AsmToken &ExclaimTok = Parser.getTok();
1026 if (ExclaimTok.is(AsmToken::Exclaim)) {
1027 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
1028 ExclaimTok.getLoc()));
1029 Parser.Lex(); // Eat exclaim token
1032 return false;
1035 /// MatchCoprocessorOperandName - Try to parse an coprocessor related
1036 /// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1037 /// "c5", ...
1038 static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1039 // Use the same layout as the tablegen'erated register name matcher. Ugly,
1040 // but efficient.
1041 switch (Name.size()) {
1042 default: break;
1043 case 2:
1044 if (Name[0] != CoprocOp)
1045 return -1;
1046 switch (Name[1]) {
1047 default: return -1;
1048 case '0': return 0;
1049 case '1': return 1;
1050 case '2': return 2;
1051 case '3': return 3;
1052 case '4': return 4;
1053 case '5': return 5;
1054 case '6': return 6;
1055 case '7': return 7;
1056 case '8': return 8;
1057 case '9': return 9;
1059 break;
1060 case 3:
1061 if (Name[0] != CoprocOp || Name[1] != '1')
1062 return -1;
1063 switch (Name[2]) {
1064 default: return -1;
1065 case '0': return 10;
1066 case '1': return 11;
1067 case '2': return 12;
1068 case '3': return 13;
1069 case '4': return 14;
1070 case '5': return 15;
1072 break;
1075 return -1;
1078 /// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1079 /// token must be an Identifier when called, and if it is a coprocessor
1080 /// number, the token is eaten and the operand is added to the operand list.
1081 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1082 tryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1083 SMLoc S = Parser.getTok().getLoc();
1084 const AsmToken &Tok = Parser.getTok();
1085 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1087 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1088 if (Num == -1)
1089 return MatchOperand_NoMatch;
1091 Parser.Lex(); // Eat identifier token.
1092 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1093 return MatchOperand_Success;
1096 /// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1097 /// token must be an Identifier when called, and if it is a coprocessor
1098 /// number, the token is eaten and the operand is added to the operand list.
1099 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1100 tryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1101 SMLoc S = Parser.getTok().getLoc();
1102 const AsmToken &Tok = Parser.getTok();
1103 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1105 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1106 if (Reg == -1)
1107 return MatchOperand_NoMatch;
1109 Parser.Lex(); // Eat identifier token.
1110 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1111 return MatchOperand_Success;
1114 /// Parse a register list, return it if successful else return null. The first
1115 /// token must be a '{' when called.
1116 bool ARMAsmParser::
1117 ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1118 assert(Parser.getTok().is(AsmToken::LCurly) &&
1119 "Token is not a Left Curly Brace");
1120 SMLoc S = Parser.getTok().getLoc();
1122 // Read the rest of the registers in the list.
1123 unsigned PrevRegNum = 0;
1124 SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1126 do {
1127 bool IsRange = Parser.getTok().is(AsmToken::Minus);
1128 Parser.Lex(); // Eat non-identifier token.
1130 const AsmToken &RegTok = Parser.getTok();
1131 SMLoc RegLoc = RegTok.getLoc();
1132 if (RegTok.isNot(AsmToken::Identifier)) {
1133 Error(RegLoc, "register expected");
1134 return true;
1137 int RegNum = TryParseRegister();
1138 if (RegNum == -1) {
1139 Error(RegLoc, "register expected");
1140 return true;
1143 if (IsRange) {
1144 int Reg = PrevRegNum;
1145 do {
1146 ++Reg;
1147 Registers.push_back(std::make_pair(Reg, RegLoc));
1148 } while (Reg != RegNum);
1149 } else {
1150 Registers.push_back(std::make_pair(RegNum, RegLoc));
1153 PrevRegNum = RegNum;
1154 } while (Parser.getTok().is(AsmToken::Comma) ||
1155 Parser.getTok().is(AsmToken::Minus));
1157 // Process the right curly brace of the list.
1158 const AsmToken &RCurlyTok = Parser.getTok();
1159 if (RCurlyTok.isNot(AsmToken::RCurly)) {
1160 Error(RCurlyTok.getLoc(), "'}' expected");
1161 return true;
1164 SMLoc E = RCurlyTok.getLoc();
1165 Parser.Lex(); // Eat right curly brace token.
1167 // Verify the register list.
1168 SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1169 RI = Registers.begin(), RE = Registers.end();
1171 unsigned HighRegNum = getARMRegisterNumbering(RI->first);
1172 bool EmittedWarning = false;
1174 DenseMap<unsigned, bool> RegMap;
1175 RegMap[HighRegNum] = true;
1177 for (++RI; RI != RE; ++RI) {
1178 const std::pair<unsigned, SMLoc> &RegInfo = *RI;
1179 unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1181 if (RegMap[Reg]) {
1182 Error(RegInfo.second, "register duplicated in register list");
1183 return true;
1186 if (!EmittedWarning && Reg < HighRegNum)
1187 Warning(RegInfo.second,
1188 "register not in ascending order in register list");
1190 RegMap[Reg] = true;
1191 HighRegNum = std::max(Reg, HighRegNum);
1194 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
1195 return false;
1198 /// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1199 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1200 tryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1201 SMLoc S = Parser.getTok().getLoc();
1202 const AsmToken &Tok = Parser.getTok();
1203 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1204 StringRef OptStr = Tok.getString();
1206 unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1207 .Case("sy", ARM_MB::SY)
1208 .Case("st", ARM_MB::ST)
1209 .Case("ish", ARM_MB::ISH)
1210 .Case("ishst", ARM_MB::ISHST)
1211 .Case("nsh", ARM_MB::NSH)
1212 .Case("nshst", ARM_MB::NSHST)
1213 .Case("osh", ARM_MB::OSH)
1214 .Case("oshst", ARM_MB::OSHST)
1215 .Default(~0U);
1217 if (Opt == ~0U)
1218 return MatchOperand_NoMatch;
1220 Parser.Lex(); // Eat identifier token.
1221 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1222 return MatchOperand_Success;
1225 /// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1226 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1227 tryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1228 SMLoc S = Parser.getTok().getLoc();
1229 const AsmToken &Tok = Parser.getTok();
1230 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1231 StringRef IFlagsStr = Tok.getString();
1233 unsigned IFlags = 0;
1234 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1235 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1236 .Case("a", ARM_PROC::A)
1237 .Case("i", ARM_PROC::I)
1238 .Case("f", ARM_PROC::F)
1239 .Default(~0U);
1241 // If some specific iflag is already set, it means that some letter is
1242 // present more than once, this is not acceptable.
1243 if (Flag == ~0U || (IFlags & Flag))
1244 return MatchOperand_NoMatch;
1246 IFlags |= Flag;
1249 Parser.Lex(); // Eat identifier token.
1250 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1251 return MatchOperand_Success;
1254 /// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1255 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1256 tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1257 SMLoc S = Parser.getTok().getLoc();
1258 const AsmToken &Tok = Parser.getTok();
1259 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1260 StringRef Mask = Tok.getString();
1262 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1263 size_t Start = 0, Next = Mask.find('_');
1264 StringRef Flags = "";
1265 StringRef SpecReg = Mask.slice(Start, Next);
1266 if (Next != StringRef::npos)
1267 Flags = Mask.slice(Next+1, Mask.size());
1269 // FlagsVal contains the complete mask:
1270 // 3-0: Mask
1271 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1272 unsigned FlagsVal = 0;
1274 if (SpecReg == "apsr") {
1275 FlagsVal = StringSwitch<unsigned>(Flags)
1276 .Case("nzcvq", 0x8) // same as CPSR_c
1277 .Case("g", 0x4) // same as CPSR_s
1278 .Case("nzcvqg", 0xc) // same as CPSR_fs
1279 .Default(~0U);
1281 if (FlagsVal == ~0U) {
1282 if (!Flags.empty())
1283 return MatchOperand_NoMatch;
1284 else
1285 FlagsVal = 0; // No flag
1287 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
1288 if (Flags == "all") // cpsr_all is an alias for cpsr_fc
1289 Flags = "fc";
1290 for (int i = 0, e = Flags.size(); i != e; ++i) {
1291 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1292 .Case("c", 1)
1293 .Case("x", 2)
1294 .Case("s", 4)
1295 .Case("f", 8)
1296 .Default(~0U);
1298 // If some specific flag is already set, it means that some letter is
1299 // present more than once, this is not acceptable.
1300 if (FlagsVal == ~0U || (FlagsVal & Flag))
1301 return MatchOperand_NoMatch;
1302 FlagsVal |= Flag;
1304 } else // No match for special register.
1305 return MatchOperand_NoMatch;
1307 // Special register without flags are equivalent to "fc" flags.
1308 if (!FlagsVal)
1309 FlagsVal = 0x9;
1311 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1312 if (SpecReg == "spsr")
1313 FlagsVal |= 16;
1315 Parser.Lex(); // Eat identifier token.
1316 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1317 return MatchOperand_Success;
1320 /// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1321 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1322 tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1323 assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1325 if (ParseMemory(Operands, ARMII::AddrMode2))
1326 return MatchOperand_NoMatch;
1328 return MatchOperand_Success;
1331 /// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1332 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
1333 tryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1334 assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1336 if (ParseMemory(Operands, ARMII::AddrMode3))
1337 return MatchOperand_NoMatch;
1339 return MatchOperand_Success;
1342 /// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1343 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1344 /// when they refer multiple MIOperands inside a single one.
1345 bool ARMAsmParser::
1346 CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1347 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1348 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1350 // Create a writeback register dummy placeholder.
1351 Inst.addOperand(MCOperand::CreateImm(0));
1353 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1354 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1355 return true;
1358 /// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1359 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1360 /// when they refer multiple MIOperands inside a single one.
1361 bool ARMAsmParser::
1362 CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1363 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1364 // Create a writeback register dummy placeholder.
1365 Inst.addOperand(MCOperand::CreateImm(0));
1366 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1367 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1368 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1369 return true;
1372 /// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1373 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1374 /// when they refer multiple MIOperands inside a single one.
1375 bool ARMAsmParser::
1376 CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1377 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1378 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1380 // Create a writeback register dummy placeholder.
1381 Inst.addOperand(MCOperand::CreateImm(0));
1383 ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1384 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1385 return true;
1388 /// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1389 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1390 /// when they refer multiple MIOperands inside a single one.
1391 bool ARMAsmParser::
1392 CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1393 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1394 // Create a writeback register dummy placeholder.
1395 Inst.addOperand(MCOperand::CreateImm(0));
1396 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1397 ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1398 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1399 return true;
1402 /// Parse an ARM memory expression, return false if successful else return true
1403 /// or an error. The first token must be a '[' when called.
1405 /// TODO Only preindexing and postindexing addressing are started, unindexed
1406 /// with option, etc are still to do.
1407 bool ARMAsmParser::
1408 ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1409 ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1410 SMLoc S, E;
1411 assert(Parser.getTok().is(AsmToken::LBrac) &&
1412 "Token is not a Left Bracket");
1413 S = Parser.getTok().getLoc();
1414 Parser.Lex(); // Eat left bracket token.
1416 const AsmToken &BaseRegTok = Parser.getTok();
1417 if (BaseRegTok.isNot(AsmToken::Identifier)) {
1418 Error(BaseRegTok.getLoc(), "register expected");
1419 return true;
1421 int BaseRegNum = TryParseRegister();
1422 if (BaseRegNum == -1) {
1423 Error(BaseRegTok.getLoc(), "register expected");
1424 return true;
1427 // The next token must either be a comma or a closing bracket.
1428 const AsmToken &Tok = Parser.getTok();
1429 if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
1430 return true;
1432 bool Preindexed = false;
1433 bool Postindexed = false;
1434 bool OffsetIsReg = false;
1435 bool Negative = false;
1436 bool Writeback = false;
1437 ARMOperand *WBOp = 0;
1438 int OffsetRegNum = -1;
1439 bool OffsetRegShifted = false;
1440 enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
1441 const MCExpr *ShiftAmount = 0;
1442 const MCExpr *Offset = 0;
1444 // First look for preindexed address forms, that is after the "[Rn" we now
1445 // have to see if the next token is a comma.
1446 if (Tok.is(AsmToken::Comma)) {
1447 Preindexed = true;
1448 Parser.Lex(); // Eat comma token.
1450 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1451 Offset, OffsetIsReg, OffsetRegNum, E))
1452 return true;
1453 const AsmToken &RBracTok = Parser.getTok();
1454 if (RBracTok.isNot(AsmToken::RBrac)) {
1455 Error(RBracTok.getLoc(), "']' expected");
1456 return true;
1458 E = RBracTok.getLoc();
1459 Parser.Lex(); // Eat right bracket token.
1461 const AsmToken &ExclaimTok = Parser.getTok();
1462 if (ExclaimTok.is(AsmToken::Exclaim)) {
1463 // None of addrmode3 instruction uses "!"
1464 if (AddrMode == ARMII::AddrMode3)
1465 return true;
1467 WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
1468 ExclaimTok.getLoc());
1469 Writeback = true;
1470 Parser.Lex(); // Eat exclaim token
1471 } else { // In addressing mode 2, pre-indexed mode always end with "!"
1472 if (AddrMode == ARMII::AddrMode2)
1473 Preindexed = false;
1475 } else {
1476 // The "[Rn" we have so far was not followed by a comma.
1478 // If there's anything other than the right brace, this is a post indexing
1479 // addressing form.
1480 E = Tok.getLoc();
1481 Parser.Lex(); // Eat right bracket token.
1483 const AsmToken &NextTok = Parser.getTok();
1485 if (NextTok.isNot(AsmToken::EndOfStatement)) {
1486 Postindexed = true;
1487 Writeback = true;
1489 if (NextTok.isNot(AsmToken::Comma)) {
1490 Error(NextTok.getLoc(), "',' expected");
1491 return true;
1494 Parser.Lex(); // Eat comma token.
1496 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
1497 ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1499 return true;
1503 // Force Offset to exist if used.
1504 if (!OffsetIsReg) {
1505 if (!Offset)
1506 Offset = MCConstantExpr::Create(0, getContext());
1507 } else {
1508 if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1509 Error(E, "shift amount not supported");
1510 return true;
1514 Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1515 Offset, OffsetRegNum, OffsetRegShifted,
1516 ShiftType, ShiftAmount, Preindexed,
1517 Postindexed, Negative, Writeback, S, E));
1518 if (WBOp)
1519 Operands.push_back(WBOp);
1521 return false;
1524 /// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
1525 /// we will parse the following (were +/- means that a plus or minus is
1526 /// optional):
1527 /// +/-Rm
1528 /// +/-Rm, shift
1529 /// #offset
1530 /// we return false on success or an error otherwise.
1531 bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1532 bool &OffsetRegShifted,
1533 enum ARM_AM::ShiftOpc &ShiftType,
1534 const MCExpr *&ShiftAmount,
1535 const MCExpr *&Offset,
1536 bool &OffsetIsReg,
1537 int &OffsetRegNum,
1538 SMLoc &E) {
1539 Negative = false;
1540 OffsetRegShifted = false;
1541 OffsetIsReg = false;
1542 OffsetRegNum = -1;
1543 const AsmToken &NextTok = Parser.getTok();
1544 E = NextTok.getLoc();
1545 if (NextTok.is(AsmToken::Plus))
1546 Parser.Lex(); // Eat plus token.
1547 else if (NextTok.is(AsmToken::Minus)) {
1548 Negative = true;
1549 Parser.Lex(); // Eat minus token
1551 // See if there is a register following the "[Rn," or "[Rn]," we have so far.
1552 const AsmToken &OffsetRegTok = Parser.getTok();
1553 if (OffsetRegTok.is(AsmToken::Identifier)) {
1554 SMLoc CurLoc = OffsetRegTok.getLoc();
1555 OffsetRegNum = TryParseRegister();
1556 if (OffsetRegNum != -1) {
1557 OffsetIsReg = true;
1558 E = CurLoc;
1562 // If we parsed a register as the offset then there can be a shift after that.
1563 if (OffsetRegNum != -1) {
1564 // Look for a comma then a shift
1565 const AsmToken &Tok = Parser.getTok();
1566 if (Tok.is(AsmToken::Comma)) {
1567 Parser.Lex(); // Eat comma token.
1569 const AsmToken &Tok = Parser.getTok();
1570 if (ParseShift(ShiftType, ShiftAmount, E))
1571 return Error(Tok.getLoc(), "shift expected");
1572 OffsetRegShifted = true;
1575 else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
1576 // Look for #offset following the "[Rn," or "[Rn],"
1577 const AsmToken &HashTok = Parser.getTok();
1578 if (HashTok.isNot(AsmToken::Hash))
1579 return Error(HashTok.getLoc(), "'#' expected");
1581 Parser.Lex(); // Eat hash token.
1583 if (getParser().ParseExpression(Offset))
1584 return true;
1585 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1587 return false;
1590 /// ParseShift as one of these two:
1591 /// ( lsl | lsr | asr | ror ) , # shift_amount
1592 /// rrx
1593 /// and returns true if it parses a shift otherwise it returns false.
1594 bool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
1595 const MCExpr *&ShiftAmount, SMLoc &E) {
1596 const AsmToken &Tok = Parser.getTok();
1597 if (Tok.isNot(AsmToken::Identifier))
1598 return true;
1599 StringRef ShiftName = Tok.getString();
1600 if (ShiftName == "lsl" || ShiftName == "LSL")
1601 St = ARM_AM::lsl;
1602 else if (ShiftName == "lsr" || ShiftName == "LSR")
1603 St = ARM_AM::lsr;
1604 else if (ShiftName == "asr" || ShiftName == "ASR")
1605 St = ARM_AM::asr;
1606 else if (ShiftName == "ror" || ShiftName == "ROR")
1607 St = ARM_AM::ror;
1608 else if (ShiftName == "rrx" || ShiftName == "RRX")
1609 St = ARM_AM::rrx;
1610 else
1611 return true;
1612 Parser.Lex(); // Eat shift type token.
1614 // Rrx stands alone.
1615 if (St == ARM_AM::rrx)
1616 return false;
1618 // Otherwise, there must be a '#' and a shift amount.
1619 const AsmToken &HashTok = Parser.getTok();
1620 if (HashTok.isNot(AsmToken::Hash))
1621 return Error(HashTok.getLoc(), "'#' expected");
1622 Parser.Lex(); // Eat hash token.
1624 if (getParser().ParseExpression(ShiftAmount))
1625 return true;
1627 return false;
1630 /// Parse a arm instruction operand. For now this parses the operand regardless
1631 /// of the mnemonic.
1632 bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1633 StringRef Mnemonic) {
1634 SMLoc S, E;
1636 // Check if the current operand has a custom associated parser, if so, try to
1637 // custom parse the operand, or fallback to the general approach.
1638 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1639 if (ResTy == MatchOperand_Success)
1640 return false;
1641 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1642 // there was a match, but an error occurred, in which case, just return that
1643 // the operand parsing failed.
1644 if (ResTy == MatchOperand_ParseFail)
1645 return true;
1647 switch (getLexer().getKind()) {
1648 default:
1649 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1650 return true;
1651 case AsmToken::Identifier:
1652 if (!TryParseRegisterWithWriteBack(Operands))
1653 return false;
1654 if (!TryParseShiftRegister(Operands))
1655 return false;
1658 // Fall though for the Identifier case that is not a register or a
1659 // special name.
1660 case AsmToken::Integer: // things like 1f and 2b as a branch targets
1661 case AsmToken::Dot: { // . as a branch target
1662 // This was not a register so parse other operands that start with an
1663 // identifier (like labels) as expressions and create them as immediates.
1664 const MCExpr *IdVal;
1665 S = Parser.getTok().getLoc();
1666 if (getParser().ParseExpression(IdVal))
1667 return true;
1668 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1669 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
1670 return false;
1672 case AsmToken::LBrac:
1673 return ParseMemory(Operands);
1674 case AsmToken::LCurly:
1675 return ParseRegisterList(Operands);
1676 case AsmToken::Hash:
1677 // #42 -> immediate.
1678 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1679 S = Parser.getTok().getLoc();
1680 Parser.Lex();
1681 const MCExpr *ImmVal;
1682 if (getParser().ParseExpression(ImmVal))
1683 return true;
1684 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1685 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
1686 return false;
1687 case AsmToken::Colon: {
1688 // ":lower16:" and ":upper16:" expression prefixes
1689 // FIXME: Check it's an expression prefix,
1690 // e.g. (FOO - :lower16:BAR) isn't legal.
1691 ARMMCExpr::VariantKind RefKind;
1692 if (ParsePrefix(RefKind))
1693 return true;
1695 const MCExpr *SubExprVal;
1696 if (getParser().ParseExpression(SubExprVal))
1697 return true;
1699 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
1700 getContext());
1701 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1702 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
1703 return false;
1708 // ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
1709 // :lower16: and :upper16:.
1710 bool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
1711 RefKind = ARMMCExpr::VK_ARM_None;
1713 // :lower16: and :upper16: modifiers
1714 assert(getLexer().is(AsmToken::Colon) && "expected a :");
1715 Parser.Lex(); // Eat ':'
1717 if (getLexer().isNot(AsmToken::Identifier)) {
1718 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
1719 return true;
1722 StringRef IDVal = Parser.getTok().getIdentifier();
1723 if (IDVal == "lower16") {
1724 RefKind = ARMMCExpr::VK_ARM_LO16;
1725 } else if (IDVal == "upper16") {
1726 RefKind = ARMMCExpr::VK_ARM_HI16;
1727 } else {
1728 Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
1729 return true;
1731 Parser.Lex();
1733 if (getLexer().isNot(AsmToken::Colon)) {
1734 Error(Parser.getTok().getLoc(), "unexpected token after prefix");
1735 return true;
1737 Parser.Lex(); // Eat the last ':'
1738 return false;
1741 const MCExpr *
1742 ARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
1743 MCSymbolRefExpr::VariantKind Variant) {
1744 // Recurse over the given expression, rebuilding it to apply the given variant
1745 // to the leftmost symbol.
1746 if (Variant == MCSymbolRefExpr::VK_None)
1747 return E;
1749 switch (E->getKind()) {
1750 case MCExpr::Target:
1751 llvm_unreachable("Can't handle target expr yet");
1752 case MCExpr::Constant:
1753 llvm_unreachable("Can't handle lower16/upper16 of constant yet");
1755 case MCExpr::SymbolRef: {
1756 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1758 if (SRE->getKind() != MCSymbolRefExpr::VK_None)
1759 return 0;
1761 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
1764 case MCExpr::Unary:
1765 llvm_unreachable("Can't handle unary expressions yet");
1767 case MCExpr::Binary: {
1768 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1769 const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
1770 const MCExpr *RHS = BE->getRHS();
1771 if (!LHS)
1772 return 0;
1774 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
1778 assert(0 && "Invalid expression kind!");
1779 return 0;
1782 /// \brief Given a mnemonic, split out possible predication code and carry
1783 /// setting letters to form a canonical mnemonic and flags.
1785 // FIXME: Would be nice to autogen this.
1786 static StringRef SplitMnemonic(StringRef Mnemonic,
1787 unsigned &PredicationCode,
1788 bool &CarrySetting,
1789 unsigned &ProcessorIMod) {
1790 PredicationCode = ARMCC::AL;
1791 CarrySetting = false;
1792 ProcessorIMod = 0;
1794 // Ignore some mnemonics we know aren't predicated forms.
1796 // FIXME: Would be nice to autogen this.
1797 if (Mnemonic == "teq" || Mnemonic == "vceq" ||
1798 Mnemonic == "movs" ||
1799 Mnemonic == "svc" ||
1800 (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
1801 Mnemonic == "vmls" || Mnemonic == "vnmls") ||
1802 Mnemonic == "vacge" || Mnemonic == "vcge" ||
1803 Mnemonic == "vclt" ||
1804 Mnemonic == "vacgt" || Mnemonic == "vcgt" ||
1805 Mnemonic == "vcle" ||
1806 (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" ||
1807 Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" ||
1808 Mnemonic == "vqdmlal" || Mnemonic == "bics"))
1809 return Mnemonic;
1811 // First, split out any predication code.
1812 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
1813 .Case("eq", ARMCC::EQ)
1814 .Case("ne", ARMCC::NE)
1815 .Case("hs", ARMCC::HS)
1816 .Case("cs", ARMCC::HS)
1817 .Case("lo", ARMCC::LO)
1818 .Case("cc", ARMCC::LO)
1819 .Case("mi", ARMCC::MI)
1820 .Case("pl", ARMCC::PL)
1821 .Case("vs", ARMCC::VS)
1822 .Case("vc", ARMCC::VC)
1823 .Case("hi", ARMCC::HI)
1824 .Case("ls", ARMCC::LS)
1825 .Case("ge", ARMCC::GE)
1826 .Case("lt", ARMCC::LT)
1827 .Case("gt", ARMCC::GT)
1828 .Case("le", ARMCC::LE)
1829 .Case("al", ARMCC::AL)
1830 .Default(~0U);
1831 if (CC != ~0U) {
1832 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
1833 PredicationCode = CC;
1836 // Next, determine if we have a carry setting bit. We explicitly ignore all
1837 // the instructions we know end in 's'.
1838 if (Mnemonic.endswith("s") &&
1839 !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
1840 Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" ||
1841 Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
1842 Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" ||
1843 Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) {
1844 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
1845 CarrySetting = true;
1848 // The "cps" instruction can have a interrupt mode operand which is glued into
1849 // the mnemonic. Check if this is the case, split it and parse the imod op
1850 if (Mnemonic.startswith("cps")) {
1851 // Split out any imod code.
1852 unsigned IMod =
1853 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
1854 .Case("ie", ARM_PROC::IE)
1855 .Case("id", ARM_PROC::ID)
1856 .Default(~0U);
1857 if (IMod != ~0U) {
1858 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
1859 ProcessorIMod = IMod;
1863 return Mnemonic;
1866 /// \brief Given a canonical mnemonic, determine if the instruction ever allows
1867 /// inclusion of carry set or predication code operands.
1869 // FIXME: It would be nice to autogen this.
1870 void ARMAsmParser::
1871 GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
1872 bool &CanAcceptPredicationCode) {
1873 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
1874 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
1875 Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
1876 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
1877 Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
1878 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
1879 Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
1880 Mnemonic == "eor" || Mnemonic == "smlal" ||
1881 (Mnemonic == "mov" && !isThumbOne())) {
1882 CanAcceptCarrySet = true;
1883 } else {
1884 CanAcceptCarrySet = false;
1887 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
1888 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
1889 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
1890 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
1891 Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" ||
1892 Mnemonic == "clrex" || Mnemonic.startswith("cps")) {
1893 CanAcceptPredicationCode = false;
1894 } else {
1895 CanAcceptPredicationCode = true;
1898 if (isThumb())
1899 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
1900 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
1901 CanAcceptPredicationCode = false;
1904 /// Parse an arm instruction mnemonic followed by its operands.
1905 bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
1906 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1907 // Create the leading tokens for the mnemonic, split by '.' characters.
1908 size_t Start = 0, Next = Name.find('.');
1909 StringRef Head = Name.slice(Start, Next);
1911 // Split out the predication code and carry setting flag from the mnemonic.
1912 unsigned PredicationCode;
1913 unsigned ProcessorIMod;
1914 bool CarrySetting;
1915 Head = SplitMnemonic(Head, PredicationCode, CarrySetting,
1916 ProcessorIMod);
1918 Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
1920 // Next, add the CCOut and ConditionCode operands, if needed.
1922 // For mnemonics which can ever incorporate a carry setting bit or predication
1923 // code, our matching model involves us always generating CCOut and
1924 // ConditionCode operands to match the mnemonic "as written" and then we let
1925 // the matcher deal with finding the right instruction or generating an
1926 // appropriate error.
1927 bool CanAcceptCarrySet, CanAcceptPredicationCode;
1928 GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode);
1930 // Add the carry setting operand, if necessary.
1932 // FIXME: It would be awesome if we could somehow invent a location such that
1933 // match errors on this operand would print a nice diagnostic about how the
1934 // 's' character in the mnemonic resulted in a CCOut operand.
1935 if (CanAcceptCarrySet) {
1936 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
1937 NameLoc));
1938 } else {
1939 // This mnemonic can't ever accept a carry set, but the user wrote one (or
1940 // misspelled another mnemonic).
1942 // FIXME: Issue a nice error.
1945 // Add the predication code operand, if necessary.
1946 if (CanAcceptPredicationCode) {
1947 Operands.push_back(ARMOperand::CreateCondCode(
1948 ARMCC::CondCodes(PredicationCode), NameLoc));
1949 } else {
1950 // This mnemonic can't ever accept a predication code, but the user wrote
1951 // one (or misspelled another mnemonic).
1953 // FIXME: Issue a nice error.
1956 // Add the processor imod operand, if necessary.
1957 if (ProcessorIMod) {
1958 Operands.push_back(ARMOperand::CreateImm(
1959 MCConstantExpr::Create(ProcessorIMod, getContext()),
1960 NameLoc, NameLoc));
1961 } else {
1962 // This mnemonic can't ever accept a imod, but the user wrote
1963 // one (or misspelled another mnemonic).
1965 // FIXME: Issue a nice error.
1968 // Add the remaining tokens in the mnemonic.
1969 while (Next != StringRef::npos) {
1970 Start = Next;
1971 Next = Name.find('.', Start + 1);
1972 StringRef ExtraToken = Name.slice(Start, Next);
1974 Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
1977 // Read the remaining operands.
1978 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1979 // Read the first operand.
1980 if (ParseOperand(Operands, Head)) {
1981 Parser.EatToEndOfStatement();
1982 return true;
1985 while (getLexer().is(AsmToken::Comma)) {
1986 Parser.Lex(); // Eat the comma.
1988 // Parse and remember the operand.
1989 if (ParseOperand(Operands, Head)) {
1990 Parser.EatToEndOfStatement();
1991 return true;
1996 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1997 Parser.EatToEndOfStatement();
1998 return TokError("unexpected token in argument list");
2001 Parser.Lex(); // Consume the EndOfStatement
2002 return false;
2005 bool ARMAsmParser::
2006 MatchAndEmitInstruction(SMLoc IDLoc,
2007 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2008 MCStreamer &Out) {
2009 MCInst Inst;
2010 unsigned ErrorInfo;
2011 MatchResultTy MatchResult, MatchResult2;
2012 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2013 if (MatchResult != Match_Success) {
2014 // If we get a Match_InvalidOperand it might be some arithmetic instruction
2015 // that does not update the condition codes. So try adding a CCOut operand
2016 // with a value of reg0.
2017 if (MatchResult == Match_InvalidOperand) {
2018 Operands.insert(Operands.begin() + 1,
2019 ARMOperand::CreateCCOut(0,
2020 ((ARMOperand*)Operands[0])->getStartLoc()));
2021 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2022 if (MatchResult2 == Match_Success)
2023 MatchResult = Match_Success;
2024 else {
2025 ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
2026 Operands.erase(Operands.begin() + 1);
2027 delete CCOut;
2030 // If we get a Match_MnemonicFail it might be some arithmetic instruction
2031 // that updates the condition codes if it ends in 's'. So see if the
2032 // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut
2033 // operand with a value of CPSR.
2034 else if (MatchResult == Match_MnemonicFail) {
2035 // Get the instruction mnemonic, which is the first token.
2036 StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken();
2037 if (Mnemonic.substr(Mnemonic.size()-1) == "s") {
2038 // removed the 's' from the mnemonic for matching.
2039 StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1);
2040 SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc();
2041 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
2042 Operands.erase(Operands.begin());
2043 delete OldMnemonic;
2044 Operands.insert(Operands.begin(),
2045 ARMOperand::CreateToken(MnemonicNoS, NameLoc));
2046 Operands.insert(Operands.begin() + 1,
2047 ARMOperand::CreateCCOut(ARM::CPSR, NameLoc));
2048 MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2049 if (MatchResult2 == Match_Success)
2050 MatchResult = Match_Success;
2051 else {
2052 ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
2053 Operands.erase(Operands.begin());
2054 delete OldMnemonic;
2055 Operands.insert(Operands.begin(),
2056 ARMOperand::CreateToken(Mnemonic, NameLoc));
2057 ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
2058 Operands.erase(Operands.begin() + 1);
2059 delete CCOut;
2064 switch (MatchResult) {
2065 case Match_Success:
2066 Out.EmitInstruction(Inst);
2067 return false;
2068 case Match_MissingFeature:
2069 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2070 return true;
2071 case Match_InvalidOperand: {
2072 SMLoc ErrorLoc = IDLoc;
2073 if (ErrorInfo != ~0U) {
2074 if (ErrorInfo >= Operands.size())
2075 return Error(IDLoc, "too few operands for instruction");
2077 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2078 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2081 return Error(ErrorLoc, "invalid operand for instruction");
2083 case Match_MnemonicFail:
2084 return Error(IDLoc, "unrecognized instruction mnemonic");
2085 case Match_ConversionFail:
2086 return Error(IDLoc, "unable to convert operands to instruction");
2089 llvm_unreachable("Implement any new match types added!");
2090 return true;
2093 /// ParseDirective parses the arm specific directives
2094 bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2095 StringRef IDVal = DirectiveID.getIdentifier();
2096 if (IDVal == ".word")
2097 return ParseDirectiveWord(4, DirectiveID.getLoc());
2098 else if (IDVal == ".thumb")
2099 return ParseDirectiveThumb(DirectiveID.getLoc());
2100 else if (IDVal == ".thumb_func")
2101 return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2102 else if (IDVal == ".code")
2103 return ParseDirectiveCode(DirectiveID.getLoc());
2104 else if (IDVal == ".syntax")
2105 return ParseDirectiveSyntax(DirectiveID.getLoc());
2106 return true;
2109 /// ParseDirectiveWord
2110 /// ::= .word [ expression (, expression)* ]
2111 bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2112 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2113 for (;;) {
2114 const MCExpr *Value;
2115 if (getParser().ParseExpression(Value))
2116 return true;
2118 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2120 if (getLexer().is(AsmToken::EndOfStatement))
2121 break;
2123 // FIXME: Improve diagnostic.
2124 if (getLexer().isNot(AsmToken::Comma))
2125 return Error(L, "unexpected token in directive");
2126 Parser.Lex();
2130 Parser.Lex();
2131 return false;
2134 /// ParseDirectiveThumb
2135 /// ::= .thumb
2136 bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2137 if (getLexer().isNot(AsmToken::EndOfStatement))
2138 return Error(L, "unexpected token in directive");
2139 Parser.Lex();
2141 // TODO: set thumb mode
2142 // TODO: tell the MC streamer the mode
2143 // getParser().getStreamer().Emit???();
2144 return false;
2147 /// ParseDirectiveThumbFunc
2148 /// ::= .thumbfunc symbol_name
2149 bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
2150 const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
2151 bool isMachO = MAI.hasSubsectionsViaSymbols();
2152 StringRef Name;
2154 // Darwin asm has function name after .thumb_func direction
2155 // ELF doesn't
2156 if (isMachO) {
2157 const AsmToken &Tok = Parser.getTok();
2158 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
2159 return Error(L, "unexpected token in .thumb_func directive");
2160 Name = Tok.getString();
2161 Parser.Lex(); // Consume the identifier token.
2164 if (getLexer().isNot(AsmToken::EndOfStatement))
2165 return Error(L, "unexpected token in directive");
2166 Parser.Lex();
2168 // FIXME: assuming function name will be the line following .thumb_func
2169 if (!isMachO) {
2170 Name = Parser.getTok().getString();
2173 // Mark symbol as a thumb symbol.
2174 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2175 getParser().getStreamer().EmitThumbFunc(Func);
2176 return false;
2179 /// ParseDirectiveSyntax
2180 /// ::= .syntax unified | divided
2181 bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
2182 const AsmToken &Tok = Parser.getTok();
2183 if (Tok.isNot(AsmToken::Identifier))
2184 return Error(L, "unexpected token in .syntax directive");
2185 StringRef Mode = Tok.getString();
2186 if (Mode == "unified" || Mode == "UNIFIED")
2187 Parser.Lex();
2188 else if (Mode == "divided" || Mode == "DIVIDED")
2189 return Error(L, "'.syntax divided' arm asssembly not supported");
2190 else
2191 return Error(L, "unrecognized syntax mode in .syntax directive");
2193 if (getLexer().isNot(AsmToken::EndOfStatement))
2194 return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2195 Parser.Lex();
2197 // TODO tell the MC streamer the mode
2198 // getParser().getStreamer().Emit???();
2199 return false;
2202 /// ParseDirectiveCode
2203 /// ::= .code 16 | 32
2204 bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
2205 const AsmToken &Tok = Parser.getTok();
2206 if (Tok.isNot(AsmToken::Integer))
2207 return Error(L, "unexpected token in .code directive");
2208 int64_t Val = Parser.getTok().getIntVal();
2209 if (Val == 16)
2210 Parser.Lex();
2211 else if (Val == 32)
2212 Parser.Lex();
2213 else
2214 return Error(L, "invalid operand to .code directive");
2216 if (getLexer().isNot(AsmToken::EndOfStatement))
2217 return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2218 Parser.Lex();
2220 if (Val == 16) {
2221 if (!isThumb())
2222 SwitchMode();
2223 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2224 } else {
2225 if (isThumb())
2226 SwitchMode();
2227 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2230 return false;
2233 extern "C" void LLVMInitializeARMAsmLexer();
2235 /// Force static initialization.
2236 extern "C" void LLVMInitializeARMAsmParser() {
2237 RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2238 RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
2239 LLVMInitializeARMAsmLexer();
2242 #define GET_REGISTER_MATCHER
2243 #define GET_MATCHER_IMPLEMENTATION
2244 #include "ARMGenAsmMatcher.inc"