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 //===----------------------------------------------------------------------===//
9
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"
33
34 using namespace llvm;
35
36 namespace {
37
38 class ARMOperand;
39
40 class ARMAsmParser : public TargetAsmParser {
41 MCSubtargetInfo &STI;
42 MCAsmParser &Parser;
43
getParser() const44 MCAsmParser &getParser() const { return Parser; }
getLexer() const45 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
46
Warning(SMLoc L,const Twine & Msg)47 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
Error(SMLoc L,const Twine & Msg)48 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
49
50 int TryParseRegister();
51 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
52 bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
53 int TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
54 bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
55 bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
56 ARMII::AddrMode AddrMode);
57 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
58 bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
59 const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
60 MCSymbolRefExpr::VariantKind Variant);
61
62
63 bool ParseMemoryOffsetReg(bool &Negative,
64 bool &OffsetRegShifted,
65 enum ARM_AM::ShiftOpc &ShiftType,
66 const MCExpr *&ShiftAmount,
67 const MCExpr *&Offset,
68 bool &OffsetIsReg,
69 int &OffsetRegNum,
70 SMLoc &E);
71 bool ParseShift(enum ARM_AM::ShiftOpc &St,
72 const MCExpr *&ShiftAmount, SMLoc &E);
73 bool ParseDirectiveWord(unsigned Size, SMLoc L);
74 bool ParseDirectiveThumb(SMLoc L);
75 bool ParseDirectiveThumbFunc(SMLoc L);
76 bool ParseDirectiveCode(SMLoc L);
77 bool ParseDirectiveSyntax(SMLoc L);
78
79 bool MatchAndEmitInstruction(SMLoc IDLoc,
80 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
81 MCStreamer &Out);
82 StringRef SplitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
83 bool &CarrySetting, unsigned &ProcessorIMod);
84 void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
85 bool &CanAcceptPredicationCode);
86
isThumb() const87 bool isThumb() const {
88 // FIXME: Can tablegen auto-generate this?
89 return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
90 }
isThumbOne() const91 bool isThumbOne() const {
92 return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
93 }
SwitchMode()94 void SwitchMode() {
95 unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
96 setAvailableFeatures(FB);
97 }
98
99 /// @name Auto-generated Match Functions
100 /// {
101
102 #define GET_ASSEMBLER_HEADER
103 #include "ARMGenAsmMatcher.inc"
104
105 /// }
106
107 OperandMatchResultTy tryParseCoprocNumOperand(
108 SmallVectorImpl<MCParsedAsmOperand*>&);
109 OperandMatchResultTy tryParseCoprocRegOperand(
110 SmallVectorImpl<MCParsedAsmOperand*>&);
111 OperandMatchResultTy tryParseMemBarrierOptOperand(
112 SmallVectorImpl<MCParsedAsmOperand*>&);
113 OperandMatchResultTy tryParseProcIFlagsOperand(
114 SmallVectorImpl<MCParsedAsmOperand*>&);
115 OperandMatchResultTy tryParseMSRMaskOperand(
116 SmallVectorImpl<MCParsedAsmOperand*>&);
117 OperandMatchResultTy tryParseMemMode2Operand(
118 SmallVectorImpl<MCParsedAsmOperand*>&);
119 OperandMatchResultTy tryParseMemMode3Operand(
120 SmallVectorImpl<MCParsedAsmOperand*>&);
121
122 // Asm Match Converter Methods
123 bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
124 const SmallVectorImpl<MCParsedAsmOperand*> &);
125 bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
126 const SmallVectorImpl<MCParsedAsmOperand*> &);
127 bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
128 const SmallVectorImpl<MCParsedAsmOperand*> &);
129 bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
130 const SmallVectorImpl<MCParsedAsmOperand*> &);
131
132 public:
ARMAsmParser(MCSubtargetInfo & _STI,MCAsmParser & _Parser)133 ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
134 : TargetAsmParser(), STI(_STI), Parser(_Parser) {
135 MCAsmParserExtension::Initialize(_Parser);
136
137 // Initialize the set of available features.
138 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
139 }
140
141 virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
142 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
143 virtual bool ParseDirective(AsmToken DirectiveID);
144 };
145 } // end anonymous namespace
146
147 namespace {
148
149 /// ARMOperand - Instances of this class represent a parsed ARM machine
150 /// instruction.
151 class ARMOperand : public MCParsedAsmOperand {
152 enum KindTy {
153 CondCode,
154 CCOut,
155 CoprocNum,
156 CoprocReg,
157 Immediate,
158 MemBarrierOpt,
159 Memory,
160 MSRMask,
161 ProcIFlags,
162 Register,
163 RegisterList,
164 DPRRegisterList,
165 SPRRegisterList,
166 ShiftedRegister,
167 Shifter,
168 Token
169 } Kind;
170
171 SMLoc StartLoc, EndLoc;
172 SmallVector<unsigned, 8> Registers;
173
174 union {
175 struct {
176 ARMCC::CondCodes Val;
177 } CC;
178
179 struct {
180 ARM_MB::MemBOpt Val;
181 } MBOpt;
182
183 struct {
184 unsigned Val;
185 } Cop;
186
187 struct {
188 ARM_PROC::IFlags Val;
189 } IFlags;
190
191 struct {
192 unsigned Val;
193 } MMask;
194
195 struct {
196 const char *Data;
197 unsigned Length;
198 } Tok;
199
200 struct {
201 unsigned RegNum;
202 } Reg;
203
204 struct {
205 const MCExpr *Val;
206 } Imm;
207
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;
225
226 struct {
227 ARM_AM::ShiftOpc ShiftTy;
228 unsigned Imm;
229 } Shift;
230 struct {
231 ARM_AM::ShiftOpc ShiftTy;
232 unsigned SrcReg;
233 unsigned ShiftReg;
234 unsigned ShiftImm;
235 } ShiftedReg;
236 };
237
ARMOperand(KindTy K)238 ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
239 public:
ARMOperand(const ARMOperand & o)240 ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
241 Kind = o.Kind;
242 StartLoc = o.StartLoc;
243 EndLoc = o.EndLoc;
244 switch (Kind) {
245 case CondCode:
246 CC = o.CC;
247 break;
248 case Token:
249 Tok = o.Tok;
250 break;
251 case CCOut:
252 case Register:
253 Reg = o.Reg;
254 break;
255 case RegisterList:
256 case DPRRegisterList:
257 case SPRRegisterList:
258 Registers = o.Registers;
259 break;
260 case CoprocNum:
261 case CoprocReg:
262 Cop = o.Cop;
263 break;
264 case Immediate:
265 Imm = o.Imm;
266 break;
267 case MemBarrierOpt:
268 MBOpt = o.MBOpt;
269 break;
270 case Memory:
271 Mem = o.Mem;
272 break;
273 case MSRMask:
274 MMask = o.MMask;
275 break;
276 case ProcIFlags:
277 IFlags = o.IFlags;
278 break;
279 case Shifter:
280 Shift = o.Shift;
281 break;
282 case ShiftedRegister:
283 ShiftedReg = o.ShiftedReg;
284 break;
285 }
286 }
287
288 /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const289 SMLoc getStartLoc() const { return StartLoc; }
290 /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const291 SMLoc getEndLoc() const { return EndLoc; }
292
getCondCode() const293 ARMCC::CondCodes getCondCode() const {
294 assert(Kind == CondCode && "Invalid access!");
295 return CC.Val;
296 }
297
getCoproc() const298 unsigned getCoproc() const {
299 assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
300 return Cop.Val;
301 }
302
getToken() const303 StringRef getToken() const {
304 assert(Kind == Token && "Invalid access!");
305 return StringRef(Tok.Data, Tok.Length);
306 }
307
getReg() const308 unsigned getReg() const {
309 assert((Kind == Register || Kind == CCOut) && "Invalid access!");
310 return Reg.RegNum;
311 }
312
getRegList() const313 const SmallVectorImpl<unsigned> &getRegList() const {
314 assert((Kind == RegisterList || Kind == DPRRegisterList ||
315 Kind == SPRRegisterList) && "Invalid access!");
316 return Registers;
317 }
318
getImm() const319 const MCExpr *getImm() const {
320 assert(Kind == Immediate && "Invalid access!");
321 return Imm.Val;
322 }
323
getMemBarrierOpt() const324 ARM_MB::MemBOpt getMemBarrierOpt() const {
325 assert(Kind == MemBarrierOpt && "Invalid access!");
326 return MBOpt.Val;
327 }
328
getProcIFlags() const329 ARM_PROC::IFlags getProcIFlags() const {
330 assert(Kind == ProcIFlags && "Invalid access!");
331 return IFlags.Val;
332 }
333
getMSRMask() const334 unsigned getMSRMask() const {
335 assert(Kind == MSRMask && "Invalid access!");
336 return MMask.Val;
337 }
338
339 /// @name Memory Operand Accessors
340 /// @{
getMemAddrMode() const341 ARMII::AddrMode getMemAddrMode() const {
342 return Mem.AddrMode;
343 }
getMemBaseRegNum() const344 unsigned getMemBaseRegNum() const {
345 return Mem.BaseRegNum;
346 }
getMemOffsetRegNum() const347 unsigned getMemOffsetRegNum() const {
348 assert(Mem.OffsetIsReg && "Invalid access!");
349 return Mem.Offset.RegNum;
350 }
getMemOffset() const351 const MCExpr *getMemOffset() const {
352 assert(!Mem.OffsetIsReg && "Invalid access!");
353 return Mem.Offset.Value;
354 }
getMemOffsetRegShifted() const355 unsigned getMemOffsetRegShifted() const {
356 assert(Mem.OffsetIsReg && "Invalid access!");
357 return Mem.OffsetRegShifted;
358 }
getMemShiftAmount() const359 const MCExpr *getMemShiftAmount() const {
360 assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
361 return Mem.ShiftAmount;
362 }
getMemShiftType() const363 enum ARM_AM::ShiftOpc getMemShiftType() const {
364 assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
365 return Mem.ShiftType;
366 }
getMemPreindexed() const367 bool getMemPreindexed() const { return Mem.Preindexed; }
getMemPostindexed() const368 bool getMemPostindexed() const { return Mem.Postindexed; }
getMemOffsetIsReg() const369 bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
getMemNegative() const370 bool getMemNegative() const { return Mem.Negative; }
getMemWriteback() const371 bool getMemWriteback() const { return Mem.Writeback; }
372
373 /// @}
374
isCoprocNum() const375 bool isCoprocNum() const { return Kind == CoprocNum; }
isCoprocReg() const376 bool isCoprocReg() const { return Kind == CoprocReg; }
isCondCode() const377 bool isCondCode() const { return Kind == CondCode; }
isCCOut() const378 bool isCCOut() const { return Kind == CCOut; }
isImm() const379 bool isImm() const { return Kind == Immediate; }
isImm0_255() const380 bool isImm0_255() const {
381 if (Kind != Immediate)
382 return false;
383 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
384 if (!CE) return false;
385 int64_t Value = CE->getValue();
386 return Value >= 0 && Value < 256;
387 }
isImm0_7() const388 bool isImm0_7() const {
389 if (Kind != Immediate)
390 return false;
391 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
392 if (!CE) return false;
393 int64_t Value = CE->getValue();
394 return Value >= 0 && Value < 8;
395 }
isImm0_15() const396 bool isImm0_15() const {
397 if (Kind != Immediate)
398 return false;
399 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
400 if (!CE) return false;
401 int64_t Value = CE->getValue();
402 return Value >= 0 && Value < 16;
403 }
isImm0_65535() const404 bool isImm0_65535() const {
405 if (Kind != Immediate)
406 return false;
407 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
408 if (!CE) return false;
409 int64_t Value = CE->getValue();
410 return Value >= 0 && Value < 65536;
411 }
isImm0_65535Expr() const412 bool isImm0_65535Expr() const {
413 if (Kind != Immediate)
414 return false;
415 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
416 // If it's not a constant expression, it'll generate a fixup and be
417 // handled later.
418 if (!CE) return true;
419 int64_t Value = CE->getValue();
420 return Value >= 0 && Value < 65536;
421 }
isARMSOImm() const422 bool isARMSOImm() const {
423 if (Kind != Immediate)
424 return false;
425 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
426 if (!CE) return false;
427 int64_t Value = CE->getValue();
428 return ARM_AM::getSOImmVal(Value) != -1;
429 }
isT2SOImm() const430 bool isT2SOImm() const {
431 if (Kind != Immediate)
432 return false;
433 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
434 if (!CE) return false;
435 int64_t Value = CE->getValue();
436 return ARM_AM::getT2SOImmVal(Value) != -1;
437 }
isReg() const438 bool isReg() const { return Kind == Register; }
isRegList() const439 bool isRegList() const { return Kind == RegisterList; }
isDPRRegList() const440 bool isDPRRegList() const { return Kind == DPRRegisterList; }
isSPRRegList() const441 bool isSPRRegList() const { return Kind == SPRRegisterList; }
isToken() const442 bool isToken() const { return Kind == Token; }
isMemBarrierOpt() const443 bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
isMemory() const444 bool isMemory() const { return Kind == Memory; }
isShifter() const445 bool isShifter() const { return Kind == Shifter; }
isShiftedReg() const446 bool isShiftedReg() const { return Kind == ShiftedRegister; }
isMemMode2() const447 bool isMemMode2() const {
448 if (getMemAddrMode() != ARMII::AddrMode2)
449 return false;
450
451 if (getMemOffsetIsReg())
452 return true;
453
454 if (getMemNegative() &&
455 !(getMemPostindexed() || getMemPreindexed()))
456 return false;
457
458 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
459 if (!CE) return false;
460 int64_t Value = CE->getValue();
461
462 // The offset must be in the range 0-4095 (imm12).
463 if (Value > 4095 || Value < -4095)
464 return false;
465
466 return true;
467 }
isMemMode3() const468 bool isMemMode3() const {
469 if (getMemAddrMode() != ARMII::AddrMode3)
470 return false;
471
472 if (getMemOffsetIsReg()) {
473 if (getMemOffsetRegShifted())
474 return false; // No shift with offset reg allowed
475 return true;
476 }
477
478 if (getMemNegative() &&
479 !(getMemPostindexed() || getMemPreindexed()))
480 return false;
481
482 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
483 if (!CE) return false;
484 int64_t Value = CE->getValue();
485
486 // The offset must be in the range 0-255 (imm8).
487 if (Value > 255 || Value < -255)
488 return false;
489
490 return true;
491 }
isMemMode5() const492 bool isMemMode5() const {
493 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
494 getMemNegative())
495 return false;
496
497 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
498 if (!CE) return false;
499
500 // The offset must be a multiple of 4 in the range 0-1020.
501 int64_t Value = CE->getValue();
502 return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
503 }
isMemMode7() const504 bool isMemMode7() const {
505 if (!isMemory() ||
506 getMemPreindexed() ||
507 getMemPostindexed() ||
508 getMemOffsetIsReg() ||
509 getMemNegative() ||
510 getMemWriteback())
511 return false;
512
513 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
514 if (!CE) return false;
515
516 if (CE->getValue())
517 return false;
518
519 return true;
520 }
isMemModeRegThumb() const521 bool isMemModeRegThumb() const {
522 if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
523 return false;
524 return true;
525 }
isMemModeImmThumb() const526 bool isMemModeImmThumb() const {
527 if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
528 return false;
529
530 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
531 if (!CE) return false;
532
533 // The offset must be a multiple of 4 in the range 0-124.
534 uint64_t Value = CE->getValue();
535 return ((Value & 0x3) == 0 && Value <= 124);
536 }
isMSRMask() const537 bool isMSRMask() const { return Kind == MSRMask; }
isProcIFlags() const538 bool isProcIFlags() const { return Kind == ProcIFlags; }
539
addExpr(MCInst & Inst,const MCExpr * Expr) const540 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
541 // Add as immediates when possible. Null MCExpr = 0.
542 if (Expr == 0)
543 Inst.addOperand(MCOperand::CreateImm(0));
544 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
545 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
546 else
547 Inst.addOperand(MCOperand::CreateExpr(Expr));
548 }
549
addCondCodeOperands(MCInst & Inst,unsigned N) const550 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
551 assert(N == 2 && "Invalid number of operands!");
552 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
553 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
554 Inst.addOperand(MCOperand::CreateReg(RegNum));
555 }
556
addCoprocNumOperands(MCInst & Inst,unsigned N) const557 void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
558 assert(N == 1 && "Invalid number of operands!");
559 Inst.addOperand(MCOperand::CreateImm(getCoproc()));
560 }
561
addCoprocRegOperands(MCInst & Inst,unsigned N) const562 void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
563 assert(N == 1 && "Invalid number of operands!");
564 Inst.addOperand(MCOperand::CreateImm(getCoproc()));
565 }
566
addCCOutOperands(MCInst & Inst,unsigned N) const567 void addCCOutOperands(MCInst &Inst, unsigned N) const {
568 assert(N == 1 && "Invalid number of operands!");
569 Inst.addOperand(MCOperand::CreateReg(getReg()));
570 }
571
addRegOperands(MCInst & Inst,unsigned N) const572 void addRegOperands(MCInst &Inst, unsigned N) const {
573 assert(N == 1 && "Invalid number of operands!");
574 Inst.addOperand(MCOperand::CreateReg(getReg()));
575 }
576
addShiftedRegOperands(MCInst & Inst,unsigned N) const577 void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
578 assert(N == 3 && "Invalid number of operands!");
579 assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
580 assert((ShiftedReg.ShiftReg == 0 ||
581 ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) == 0) &&
582 "Invalid shifted register operand!");
583 Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
584 Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
585 Inst.addOperand(MCOperand::CreateImm(
586 ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
587 }
588
addShifterOperands(MCInst & Inst,unsigned N) const589 void addShifterOperands(MCInst &Inst, unsigned N) const {
590 assert(N == 1 && "Invalid number of operands!");
591 Inst.addOperand(MCOperand::CreateImm(
592 ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
593 }
594
addRegListOperands(MCInst & Inst,unsigned N) const595 void addRegListOperands(MCInst &Inst, unsigned N) const {
596 assert(N == 1 && "Invalid number of operands!");
597 const SmallVectorImpl<unsigned> &RegList = getRegList();
598 for (SmallVectorImpl<unsigned>::const_iterator
599 I = RegList.begin(), E = RegList.end(); I != E; ++I)
600 Inst.addOperand(MCOperand::CreateReg(*I));
601 }
602
addDPRRegListOperands(MCInst & Inst,unsigned N) const603 void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
604 addRegListOperands(Inst, N);
605 }
606
addSPRRegListOperands(MCInst & Inst,unsigned N) const607 void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
608 addRegListOperands(Inst, N);
609 }
610
addImmOperands(MCInst & Inst,unsigned N) const611 void addImmOperands(MCInst &Inst, unsigned N) const {
612 assert(N == 1 && "Invalid number of operands!");
613 addExpr(Inst, getImm());
614 }
615
addImm0_255Operands(MCInst & Inst,unsigned N) const616 void addImm0_255Operands(MCInst &Inst, unsigned N) const {
617 assert(N == 1 && "Invalid number of operands!");
618 addExpr(Inst, getImm());
619 }
620
addImm0_7Operands(MCInst & Inst,unsigned N) const621 void addImm0_7Operands(MCInst &Inst, unsigned N) const {
622 assert(N == 1 && "Invalid number of operands!");
623 addExpr(Inst, getImm());
624 }
625
addImm0_15Operands(MCInst & Inst,unsigned N) const626 void addImm0_15Operands(MCInst &Inst, unsigned N) const {
627 assert(N == 1 && "Invalid number of operands!");
628 addExpr(Inst, getImm());
629 }
630
addImm0_65535Operands(MCInst & Inst,unsigned N) const631 void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
632 assert(N == 1 && "Invalid number of operands!");
633 addExpr(Inst, getImm());
634 }
635
addImm0_65535ExprOperands(MCInst & Inst,unsigned N) const636 void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
637 assert(N == 1 && "Invalid number of operands!");
638 addExpr(Inst, getImm());
639 }
640
addARMSOImmOperands(MCInst & Inst,unsigned N) const641 void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
642 assert(N == 1 && "Invalid number of operands!");
643 addExpr(Inst, getImm());
644 }
645
addT2SOImmOperands(MCInst & Inst,unsigned N) const646 void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
647 assert(N == 1 && "Invalid number of operands!");
648 addExpr(Inst, getImm());
649 }
650
addMemBarrierOptOperands(MCInst & Inst,unsigned N) const651 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
652 assert(N == 1 && "Invalid number of operands!");
653 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
654 }
655
addMemMode7Operands(MCInst & Inst,unsigned N) const656 void addMemMode7Operands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && isMemMode7() && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
659
660 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
661 (void)CE;
662 assert((CE || CE->getValue() == 0) &&
663 "No offset operand support in mode 7");
664 }
665
addMemMode2Operands(MCInst & Inst,unsigned N) const666 void addMemMode2Operands(MCInst &Inst, unsigned N) const {
667 assert(isMemMode2() && "Invalid mode or number of operands!");
668 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
669 unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
670
671 if (getMemOffsetIsReg()) {
672 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
673
674 ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
675 ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
676 int64_t ShiftAmount = 0;
677
678 if (getMemOffsetRegShifted()) {
679 ShOpc = getMemShiftType();
680 const MCConstantExpr *CE =
681 dyn_cast<MCConstantExpr>(getMemShiftAmount());
682 ShiftAmount = CE->getValue();
683 }
684
685 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
686 ShOpc, IdxMode)));
687 return;
688 }
689
690 // Create a operand placeholder to always yield the same number of operands.
691 Inst.addOperand(MCOperand::CreateReg(0));
692
693 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
694 // the difference?
695 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
696 assert(CE && "Non-constant mode 2 offset operand!");
697 int64_t Offset = CE->getValue();
698
699 if (Offset >= 0)
700 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
701 Offset, ARM_AM::no_shift, IdxMode)));
702 else
703 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
704 -Offset, ARM_AM::no_shift, IdxMode)));
705 }
706
addMemMode3Operands(MCInst & Inst,unsigned N) const707 void addMemMode3Operands(MCInst &Inst, unsigned N) const {
708 assert(isMemMode3() && "Invalid mode or number of operands!");
709 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
710 unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
711
712 if (getMemOffsetIsReg()) {
713 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
714
715 ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
716 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
717 IdxMode)));
718 return;
719 }
720
721 // Create a operand placeholder to always yield the same number of operands.
722 Inst.addOperand(MCOperand::CreateReg(0));
723
724 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
725 // the difference?
726 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
727 assert(CE && "Non-constant mode 3 offset operand!");
728 int64_t Offset = CE->getValue();
729
730 if (Offset >= 0)
731 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
732 Offset, IdxMode)));
733 else
734 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
735 -Offset, IdxMode)));
736 }
737
addMemMode5Operands(MCInst & Inst,unsigned N) const738 void addMemMode5Operands(MCInst &Inst, unsigned N) const {
739 assert(N == 2 && isMemMode5() && "Invalid number of operands!");
740
741 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
742 assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
743
744 // FIXME: #-0 is encoded differently than #0. Does the parser preserve
745 // the difference?
746 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
747 assert(CE && "Non-constant mode 5 offset operand!");
748
749 // The MCInst offset operand doesn't include the low two bits (like
750 // the instruction encoding).
751 int64_t Offset = CE->getValue() / 4;
752 if (Offset >= 0)
753 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
754 Offset)));
755 else
756 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
757 -Offset)));
758 }
759
addMemModeRegThumbOperands(MCInst & Inst,unsigned N) const760 void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
761 assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
762 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
763 Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
764 }
765
addMemModeImmThumbOperands(MCInst & Inst,unsigned N) const766 void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
767 assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
769 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
770 assert(CE && "Non-constant mode offset operand!");
771 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
772 }
773
addMSRMaskOperands(MCInst & Inst,unsigned N) const774 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 1 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
777 }
778
addProcIFlagsOperands(MCInst & Inst,unsigned N) const779 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
782 }
783
784 virtual void print(raw_ostream &OS) const;
785
CreateCondCode(ARMCC::CondCodes CC,SMLoc S)786 static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
787 ARMOperand *Op = new ARMOperand(CondCode);
788 Op->CC.Val = CC;
789 Op->StartLoc = S;
790 Op->EndLoc = S;
791 return Op;
792 }
793
CreateCoprocNum(unsigned CopVal,SMLoc S)794 static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
795 ARMOperand *Op = new ARMOperand(CoprocNum);
796 Op->Cop.Val = CopVal;
797 Op->StartLoc = S;
798 Op->EndLoc = S;
799 return Op;
800 }
801
CreateCoprocReg(unsigned CopVal,SMLoc S)802 static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
803 ARMOperand *Op = new ARMOperand(CoprocReg);
804 Op->Cop.Val = CopVal;
805 Op->StartLoc = S;
806 Op->EndLoc = S;
807 return Op;
808 }
809
CreateCCOut(unsigned RegNum,SMLoc S)810 static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
811 ARMOperand *Op = new ARMOperand(CCOut);
812 Op->Reg.RegNum = RegNum;
813 Op->StartLoc = S;
814 Op->EndLoc = S;
815 return Op;
816 }
817
CreateToken(StringRef Str,SMLoc S)818 static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
819 ARMOperand *Op = new ARMOperand(Token);
820 Op->Tok.Data = Str.data();
821 Op->Tok.Length = Str.size();
822 Op->StartLoc = S;
823 Op->EndLoc = S;
824 return Op;
825 }
826
CreateReg(unsigned RegNum,SMLoc S,SMLoc E)827 static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
828 ARMOperand *Op = new ARMOperand(Register);
829 Op->Reg.RegNum = RegNum;
830 Op->StartLoc = S;
831 Op->EndLoc = E;
832 return Op;
833 }
834
CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,unsigned SrcReg,unsigned ShiftReg,unsigned ShiftImm,SMLoc S,SMLoc E)835 static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
836 unsigned SrcReg,
837 unsigned ShiftReg,
838 unsigned ShiftImm,
839 SMLoc S, SMLoc E) {
840 ARMOperand *Op = new ARMOperand(ShiftedRegister);
841 Op->ShiftedReg.ShiftTy = ShTy;
842 Op->ShiftedReg.SrcReg = SrcReg;
843 Op->ShiftedReg.ShiftReg = ShiftReg;
844 Op->ShiftedReg.ShiftImm = ShiftImm;
845 Op->StartLoc = S;
846 Op->EndLoc = E;
847 return Op;
848 }
849
CreateShifter(ARM_AM::ShiftOpc ShTy,SMLoc S,SMLoc E)850 static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
851 SMLoc S, SMLoc E) {
852 ARMOperand *Op = new ARMOperand(Shifter);
853 Op->Shift.ShiftTy = ShTy;
854 Op->StartLoc = S;
855 Op->EndLoc = E;
856 return Op;
857 }
858
859 static ARMOperand *
CreateRegList(const SmallVectorImpl<std::pair<unsigned,SMLoc>> & Regs,SMLoc StartLoc,SMLoc EndLoc)860 CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
861 SMLoc StartLoc, SMLoc EndLoc) {
862 KindTy Kind = RegisterList;
863
864 if (ARM::DPRRegClass.contains(Regs.front().first))
865 Kind = DPRRegisterList;
866 else if (ARM::SPRRegClass.contains(Regs.front().first))
867 Kind = SPRRegisterList;
868
869 ARMOperand *Op = new ARMOperand(Kind);
870 for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
871 I = Regs.begin(), E = Regs.end(); I != E; ++I)
872 Op->Registers.push_back(I->first);
873 array_pod_sort(Op->Registers.begin(), Op->Registers.end());
874 Op->StartLoc = StartLoc;
875 Op->EndLoc = EndLoc;
876 return Op;
877 }
878
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E)879 static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
880 ARMOperand *Op = new ARMOperand(Immediate);
881 Op->Imm.Val = Val;
882 Op->StartLoc = S;
883 Op->EndLoc = E;
884 return Op;
885 }
886
CreateMem(ARMII::AddrMode AddrMode,unsigned BaseRegNum,bool OffsetIsReg,const MCExpr * Offset,int OffsetRegNum,bool OffsetRegShifted,enum ARM_AM::ShiftOpc ShiftType,const MCExpr * ShiftAmount,bool Preindexed,bool Postindexed,bool Negative,bool Writeback,SMLoc S,SMLoc E)887 static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
888 bool OffsetIsReg, const MCExpr *Offset,
889 int OffsetRegNum, bool OffsetRegShifted,
890 enum ARM_AM::ShiftOpc ShiftType,
891 const MCExpr *ShiftAmount, bool Preindexed,
892 bool Postindexed, bool Negative, bool Writeback,
893 SMLoc S, SMLoc E) {
894 assert((OffsetRegNum == -1 || OffsetIsReg) &&
895 "OffsetRegNum must imply OffsetIsReg!");
896 assert((!OffsetRegShifted || OffsetIsReg) &&
897 "OffsetRegShifted must imply OffsetIsReg!");
898 assert((Offset || OffsetIsReg) &&
899 "Offset must exists unless register offset is used!");
900 assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
901 "Cannot have shift amount without shifted register offset!");
902 assert((!Offset || !OffsetIsReg) &&
903 "Cannot have expression offset and register offset!");
904
905 ARMOperand *Op = new ARMOperand(Memory);
906 Op->Mem.AddrMode = AddrMode;
907 Op->Mem.BaseRegNum = BaseRegNum;
908 Op->Mem.OffsetIsReg = OffsetIsReg;
909 if (OffsetIsReg)
910 Op->Mem.Offset.RegNum = OffsetRegNum;
911 else
912 Op->Mem.Offset.Value = Offset;
913 Op->Mem.OffsetRegShifted = OffsetRegShifted;
914 Op->Mem.ShiftType = ShiftType;
915 Op->Mem.ShiftAmount = ShiftAmount;
916 Op->Mem.Preindexed = Preindexed;
917 Op->Mem.Postindexed = Postindexed;
918 Op->Mem.Negative = Negative;
919 Op->Mem.Writeback = Writeback;
920
921 Op->StartLoc = S;
922 Op->EndLoc = E;
923 return Op;
924 }
925
CreateMemBarrierOpt(ARM_MB::MemBOpt Opt,SMLoc S)926 static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
927 ARMOperand *Op = new ARMOperand(MemBarrierOpt);
928 Op->MBOpt.Val = Opt;
929 Op->StartLoc = S;
930 Op->EndLoc = S;
931 return Op;
932 }
933
CreateProcIFlags(ARM_PROC::IFlags IFlags,SMLoc S)934 static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
935 ARMOperand *Op = new ARMOperand(ProcIFlags);
936 Op->IFlags.Val = IFlags;
937 Op->StartLoc = S;
938 Op->EndLoc = S;
939 return Op;
940 }
941
CreateMSRMask(unsigned MMask,SMLoc S)942 static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
943 ARMOperand *Op = new ARMOperand(MSRMask);
944 Op->MMask.Val = MMask;
945 Op->StartLoc = S;
946 Op->EndLoc = S;
947 return Op;
948 }
949 };
950
951 } // end anonymous namespace.
952
print(raw_ostream & OS) const953 void ARMOperand::print(raw_ostream &OS) const {
954 switch (Kind) {
955 case CondCode:
956 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
957 break;
958 case CCOut:
959 OS << "<ccout " << getReg() << ">";
960 break;
961 case CoprocNum:
962 OS << "<coprocessor number: " << getCoproc() << ">";
963 break;
964 case CoprocReg:
965 OS << "<coprocessor register: " << getCoproc() << ">";
966 break;
967 case MSRMask:
968 OS << "<mask: " << getMSRMask() << ">";
969 break;
970 case Immediate:
971 getImm()->print(OS);
972 break;
973 case MemBarrierOpt:
974 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
975 break;
976 case Memory:
977 OS << "<memory "
978 << "am:" << ARMII::AddrModeToString(getMemAddrMode())
979 << " base:" << getMemBaseRegNum();
980 if (getMemOffsetIsReg()) {
981 OS << " offset:<register " << getMemOffsetRegNum();
982 if (getMemOffsetRegShifted()) {
983 OS << " offset-shift-type:" << getMemShiftType();
984 OS << " offset-shift-amount:" << *getMemShiftAmount();
985 }
986 } else {
987 OS << " offset:" << *getMemOffset();
988 }
989 if (getMemOffsetIsReg())
990 OS << " (offset-is-reg)";
991 if (getMemPreindexed())
992 OS << " (pre-indexed)";
993 if (getMemPostindexed())
994 OS << " (post-indexed)";
995 if (getMemNegative())
996 OS << " (negative)";
997 if (getMemWriteback())
998 OS << " (writeback)";
999 OS << ">";
1000 break;
1001 case ProcIFlags: {
1002 OS << "<ARM_PROC::";
1003 unsigned IFlags = getProcIFlags();
1004 for (int i=2; i >= 0; --i)
1005 if (IFlags & (1 << i))
1006 OS << ARM_PROC::IFlagsToString(1 << i);
1007 OS << ">";
1008 break;
1009 }
1010 case Register:
1011 OS << "<register " << getReg() << ">";
1012 break;
1013 case Shifter:
1014 OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
1015 break;
1016 case ShiftedRegister:
1017 OS << "<so_reg"
1018 << ShiftedReg.SrcReg
1019 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
1020 << ", " << ShiftedReg.ShiftReg << ", "
1021 << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
1022 << ">";
1023 break;
1024 case RegisterList:
1025 case DPRRegisterList:
1026 case SPRRegisterList: {
1027 OS << "<register_list ";
1028
1029 const SmallVectorImpl<unsigned> &RegList = getRegList();
1030 for (SmallVectorImpl<unsigned>::const_iterator
1031 I = RegList.begin(), E = RegList.end(); I != E; ) {
1032 OS << *I;
1033 if (++I < E) OS << ", ";
1034 }
1035
1036 OS << ">";
1037 break;
1038 }
1039 case Token:
1040 OS << "'" << getToken() << "'";
1041 break;
1042 }
1043 }
1044
1045 /// @name Auto-generated Match Functions
1046 /// {
1047
1048 static unsigned MatchRegisterName(StringRef Name);
1049
1050 /// }
1051
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1052 bool ARMAsmParser::ParseRegister(unsigned &RegNo,
1053 SMLoc &StartLoc, SMLoc &EndLoc) {
1054 RegNo = TryParseRegister();
1055
1056 return (RegNo == (unsigned)-1);
1057 }
1058
1059 /// Try to parse a register name. The token must be an Identifier when called,
1060 /// and if it is a register name the token is eaten and the register number is
1061 /// returned. Otherwise return -1.
1062 ///
TryParseRegister()1063 int ARMAsmParser::TryParseRegister() {
1064 const AsmToken &Tok = Parser.getTok();
1065 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1066
1067 // FIXME: Validate register for the current architecture; we have to do
1068 // validation later, so maybe there is no need for this here.
1069 std::string upperCase = Tok.getString().str();
1070 std::string lowerCase = LowercaseString(upperCase);
1071 unsigned RegNum = MatchRegisterName(lowerCase);
1072 if (!RegNum) {
1073 RegNum = StringSwitch<unsigned>(lowerCase)
1074 .Case("r13", ARM::SP)
1075 .Case("r14", ARM::LR)
1076 .Case("r15", ARM::PC)
1077 .Case("ip", ARM::R12)
1078 .Default(0);
1079 }
1080 if (!RegNum) return -1;
1081
1082 Parser.Lex(); // Eat identifier token.
1083 return RegNum;
1084 }
1085
1086 // Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0.
1087 // If a recoverable error occurs, return 1. If an irrecoverable error
1088 // occurs, return -1. An irrecoverable error is one where tokens have been
1089 // consumed in the process of trying to parse the shifter (i.e., when it is
1090 // indeed a shifter operand, but malformed).
TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1091 int ARMAsmParser::TryParseShiftRegister(
1092 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1093 SMLoc S = Parser.getTok().getLoc();
1094 const AsmToken &Tok = Parser.getTok();
1095 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1096
1097 std::string upperCase = Tok.getString().str();
1098 std::string lowerCase = LowercaseString(upperCase);
1099 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
1100 .Case("lsl", ARM_AM::lsl)
1101 .Case("lsr", ARM_AM::lsr)
1102 .Case("asr", ARM_AM::asr)
1103 .Case("ror", ARM_AM::ror)
1104 .Case("rrx", ARM_AM::rrx)
1105 .Default(ARM_AM::no_shift);
1106
1107 if (ShiftTy == ARM_AM::no_shift)
1108 return 1;
1109
1110 Parser.Lex(); // Eat the operator.
1111
1112 // The source register for the shift has already been added to the
1113 // operand list, so we need to pop it off and combine it into the shifted
1114 // register operand instead.
1115 OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1116 if (!PrevOp->isReg())
1117 return Error(PrevOp->getStartLoc(), "shift must be of a register");
1118 int SrcReg = PrevOp->getReg();
1119 int64_t Imm = 0;
1120 int ShiftReg = 0;
1121 if (ShiftTy == ARM_AM::rrx) {
1122 // RRX Doesn't have an explicit shift amount. The encoder expects
1123 // the shift register to be the same as the source register. Seems odd,
1124 // but OK.
1125 ShiftReg = SrcReg;
1126 } else {
1127 // Figure out if this is shifted by a constant or a register (for non-RRX).
1128 if (Parser.getTok().is(AsmToken::Hash)) {
1129 Parser.Lex(); // Eat hash.
1130 SMLoc ImmLoc = Parser.getTok().getLoc();
1131 const MCExpr *ShiftExpr = 0;
1132 if (getParser().ParseExpression(ShiftExpr)) {
1133 Error(ImmLoc, "invalid immediate shift value");
1134 return -1;
1135 }
1136 // The expression must be evaluatable as an immediate.
1137 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
1138 if (!CE) {
1139 Error(ImmLoc, "invalid immediate shift value");
1140 return -1;
1141 }
1142 // Range check the immediate.
1143 // lsl, ror: 0 <= imm <= 31
1144 // lsr, asr: 0 <= imm <= 32
1145 Imm = CE->getValue();
1146 if (Imm < 0 ||
1147 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1148 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
1149 Error(ImmLoc, "immediate shift value out of range");
1150 return -1;
1151 }
1152 } else if (Parser.getTok().is(AsmToken::Identifier)) {
1153 ShiftReg = TryParseRegister();
1154 SMLoc L = Parser.getTok().getLoc();
1155 if (ShiftReg == -1) {
1156 Error (L, "expected immediate or register in shift operand");
1157 return -1;
1158 }
1159 } else {
1160 Error (Parser.getTok().getLoc(),
1161 "expected immediate or register in shift operand");
1162 return -1;
1163 }
1164 }
1165
1166 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1167 ShiftReg, Imm,
1168 S, Parser.getTok().getLoc()));
1169
1170 return 0;
1171 }
1172
1173
1174 /// Try to parse a register name. The token must be an Identifier when called.
1175 /// If it's a register, an AsmOperand is created. Another AsmOperand is created
1176 /// if there is a "writeback". 'true' if it's not a register.
1177 ///
1178 /// TODO this is likely to change to allow different register types and or to
1179 /// parse for a specific register type.
1180 bool ARMAsmParser::
TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1181 TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1182 SMLoc S = Parser.getTok().getLoc();
1183 int RegNo = TryParseRegister();
1184 if (RegNo == -1)
1185 return true;
1186
1187 Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1188
1189 const AsmToken &ExclaimTok = Parser.getTok();
1190 if (ExclaimTok.is(AsmToken::Exclaim)) {
1191 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
1192 ExclaimTok.getLoc()));
1193 Parser.Lex(); // Eat exclaim token
1194 }
1195
1196 return false;
1197 }
1198
1199 /// MatchCoprocessorOperandName - Try to parse an coprocessor related
1200 /// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1201 /// "c5", ...
MatchCoprocessorOperandName(StringRef Name,char CoprocOp)1202 static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1203 // Use the same layout as the tablegen'erated register name matcher. Ugly,
1204 // but efficient.
1205 switch (Name.size()) {
1206 default: break;
1207 case 2:
1208 if (Name[0] != CoprocOp)
1209 return -1;
1210 switch (Name[1]) {
1211 default: return -1;
1212 case '0': return 0;
1213 case '1': return 1;
1214 case '2': return 2;
1215 case '3': return 3;
1216 case '4': return 4;
1217 case '5': return 5;
1218 case '6': return 6;
1219 case '7': return 7;
1220 case '8': return 8;
1221 case '9': return 9;
1222 }
1223 break;
1224 case 3:
1225 if (Name[0] != CoprocOp || Name[1] != '1')
1226 return -1;
1227 switch (Name[2]) {
1228 default: return -1;
1229 case '0': return 10;
1230 case '1': return 11;
1231 case '2': return 12;
1232 case '3': return 13;
1233 case '4': return 14;
1234 case '5': return 15;
1235 }
1236 break;
1237 }
1238
1239 return -1;
1240 }
1241
1242 /// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1243 /// token must be an Identifier when called, and if it is a coprocessor
1244 /// number, the token is eaten and the operand is added to the operand list.
1245 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
tryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1246 tryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1247 SMLoc S = Parser.getTok().getLoc();
1248 const AsmToken &Tok = Parser.getTok();
1249 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1250
1251 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1252 if (Num == -1)
1253 return MatchOperand_NoMatch;
1254
1255 Parser.Lex(); // Eat identifier token.
1256 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1257 return MatchOperand_Success;
1258 }
1259
1260 /// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1261 /// token must be an Identifier when called, and if it is a coprocessor
1262 /// number, the token is eaten and the operand is added to the operand list.
1263 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
tryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1264 tryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1265 SMLoc S = Parser.getTok().getLoc();
1266 const AsmToken &Tok = Parser.getTok();
1267 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1268
1269 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1270 if (Reg == -1)
1271 return MatchOperand_NoMatch;
1272
1273 Parser.Lex(); // Eat identifier token.
1274 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1275 return MatchOperand_Success;
1276 }
1277
1278 /// Parse a register list, return it if successful else return null. The first
1279 /// token must be a '{' when called.
1280 bool ARMAsmParser::
ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1281 ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1282 assert(Parser.getTok().is(AsmToken::LCurly) &&
1283 "Token is not a Left Curly Brace");
1284 SMLoc S = Parser.getTok().getLoc();
1285
1286 // Read the rest of the registers in the list.
1287 unsigned PrevRegNum = 0;
1288 SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1289
1290 do {
1291 bool IsRange = Parser.getTok().is(AsmToken::Minus);
1292 Parser.Lex(); // Eat non-identifier token.
1293
1294 const AsmToken &RegTok = Parser.getTok();
1295 SMLoc RegLoc = RegTok.getLoc();
1296 if (RegTok.isNot(AsmToken::Identifier)) {
1297 Error(RegLoc, "register expected");
1298 return true;
1299 }
1300
1301 int RegNum = TryParseRegister();
1302 if (RegNum == -1) {
1303 Error(RegLoc, "register expected");
1304 return true;
1305 }
1306
1307 if (IsRange) {
1308 int Reg = PrevRegNum;
1309 do {
1310 ++Reg;
1311 Registers.push_back(std::make_pair(Reg, RegLoc));
1312 } while (Reg != RegNum);
1313 } else {
1314 Registers.push_back(std::make_pair(RegNum, RegLoc));
1315 }
1316
1317 PrevRegNum = RegNum;
1318 } while (Parser.getTok().is(AsmToken::Comma) ||
1319 Parser.getTok().is(AsmToken::Minus));
1320
1321 // Process the right curly brace of the list.
1322 const AsmToken &RCurlyTok = Parser.getTok();
1323 if (RCurlyTok.isNot(AsmToken::RCurly)) {
1324 Error(RCurlyTok.getLoc(), "'}' expected");
1325 return true;
1326 }
1327
1328 SMLoc E = RCurlyTok.getLoc();
1329 Parser.Lex(); // Eat right curly brace token.
1330
1331 // Verify the register list.
1332 SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1333 RI = Registers.begin(), RE = Registers.end();
1334
1335 unsigned HighRegNum = getARMRegisterNumbering(RI->first);
1336 bool EmittedWarning = false;
1337
1338 DenseMap<unsigned, bool> RegMap;
1339 RegMap[HighRegNum] = true;
1340
1341 for (++RI; RI != RE; ++RI) {
1342 const std::pair<unsigned, SMLoc> &RegInfo = *RI;
1343 unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1344
1345 if (RegMap[Reg]) {
1346 Error(RegInfo.second, "register duplicated in register list");
1347 return true;
1348 }
1349
1350 if (!EmittedWarning && Reg < HighRegNum)
1351 Warning(RegInfo.second,
1352 "register not in ascending order in register list");
1353
1354 RegMap[Reg] = true;
1355 HighRegNum = std::max(Reg, HighRegNum);
1356 }
1357
1358 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
1359 return false;
1360 }
1361
1362 /// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1363 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
tryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1364 tryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1365 SMLoc S = Parser.getTok().getLoc();
1366 const AsmToken &Tok = Parser.getTok();
1367 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1368 StringRef OptStr = Tok.getString();
1369
1370 unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1371 .Case("sy", ARM_MB::SY)
1372 .Case("st", ARM_MB::ST)
1373 .Case("sh", ARM_MB::ISH)
1374 .Case("ish", ARM_MB::ISH)
1375 .Case("shst", ARM_MB::ISHST)
1376 .Case("ishst", ARM_MB::ISHST)
1377 .Case("nsh", ARM_MB::NSH)
1378 .Case("un", ARM_MB::NSH)
1379 .Case("nshst", ARM_MB::NSHST)
1380 .Case("unst", ARM_MB::NSHST)
1381 .Case("osh", ARM_MB::OSH)
1382 .Case("oshst", ARM_MB::OSHST)
1383 .Default(~0U);
1384
1385 if (Opt == ~0U)
1386 return MatchOperand_NoMatch;
1387
1388 Parser.Lex(); // Eat identifier token.
1389 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1390 return MatchOperand_Success;
1391 }
1392
1393 /// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1394 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
tryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1395 tryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1396 SMLoc S = Parser.getTok().getLoc();
1397 const AsmToken &Tok = Parser.getTok();
1398 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1399 StringRef IFlagsStr = Tok.getString();
1400
1401 unsigned IFlags = 0;
1402 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1403 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1404 .Case("a", ARM_PROC::A)
1405 .Case("i", ARM_PROC::I)
1406 .Case("f", ARM_PROC::F)
1407 .Default(~0U);
1408
1409 // If some specific iflag is already set, it means that some letter is
1410 // present more than once, this is not acceptable.
1411 if (Flag == ~0U || (IFlags & Flag))
1412 return MatchOperand_NoMatch;
1413
1414 IFlags |= Flag;
1415 }
1416
1417 Parser.Lex(); // Eat identifier token.
1418 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1419 return MatchOperand_Success;
1420 }
1421
1422 /// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1423 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1424 tryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1425 SMLoc S = Parser.getTok().getLoc();
1426 const AsmToken &Tok = Parser.getTok();
1427 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1428 StringRef Mask = Tok.getString();
1429
1430 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1431 size_t Start = 0, Next = Mask.find('_');
1432 StringRef Flags = "";
1433 std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
1434 if (Next != StringRef::npos)
1435 Flags = Mask.slice(Next+1, Mask.size());
1436
1437 // FlagsVal contains the complete mask:
1438 // 3-0: Mask
1439 // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1440 unsigned FlagsVal = 0;
1441
1442 if (SpecReg == "apsr") {
1443 FlagsVal = StringSwitch<unsigned>(Flags)
1444 .Case("nzcvq", 0x8) // same as CPSR_f
1445 .Case("g", 0x4) // same as CPSR_s
1446 .Case("nzcvqg", 0xc) // same as CPSR_fs
1447 .Default(~0U);
1448
1449 if (FlagsVal == ~0U) {
1450 if (!Flags.empty())
1451 return MatchOperand_NoMatch;
1452 else
1453 FlagsVal = 0; // No flag
1454 }
1455 } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
1456 if (Flags == "all") // cpsr_all is an alias for cpsr_fc
1457 Flags = "fc";
1458 for (int i = 0, e = Flags.size(); i != e; ++i) {
1459 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1460 .Case("c", 1)
1461 .Case("x", 2)
1462 .Case("s", 4)
1463 .Case("f", 8)
1464 .Default(~0U);
1465
1466 // If some specific flag is already set, it means that some letter is
1467 // present more than once, this is not acceptable.
1468 if (FlagsVal == ~0U || (FlagsVal & Flag))
1469 return MatchOperand_NoMatch;
1470 FlagsVal |= Flag;
1471 }
1472 } else // No match for special register.
1473 return MatchOperand_NoMatch;
1474
1475 // Special register without flags are equivalent to "fc" flags.
1476 if (!FlagsVal)
1477 FlagsVal = 0x9;
1478
1479 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1480 if (SpecReg == "spsr")
1481 FlagsVal |= 16;
1482
1483 Parser.Lex(); // Eat identifier token.
1484 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1485 return MatchOperand_Success;
1486 }
1487
1488 /// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1489 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1490 tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1491 assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1492
1493 if (ParseMemory(Operands, ARMII::AddrMode2))
1494 return MatchOperand_NoMatch;
1495
1496 return MatchOperand_Success;
1497 }
1498
1499 /// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1500 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
tryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand * > & Operands)1501 tryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1502 assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1503
1504 if (ParseMemory(Operands, ARMII::AddrMode3))
1505 return MatchOperand_NoMatch;
1506
1507 return MatchOperand_Success;
1508 }
1509
1510 /// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1511 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1512 /// when they refer multiple MIOperands inside a single one.
1513 bool ARMAsmParser::
CvtLdWriteBackRegAddrMode2(MCInst & Inst,unsigned Opcode,const SmallVectorImpl<MCParsedAsmOperand * > & Operands)1514 CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1515 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1516 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1517
1518 // Create a writeback register dummy placeholder.
1519 Inst.addOperand(MCOperand::CreateImm(0));
1520
1521 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1522 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1523 return true;
1524 }
1525
1526 /// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1527 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1528 /// when they refer multiple MIOperands inside a single one.
1529 bool ARMAsmParser::
CvtStWriteBackRegAddrMode2(MCInst & Inst,unsigned Opcode,const SmallVectorImpl<MCParsedAsmOperand * > & Operands)1530 CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1531 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1532 // Create a writeback register dummy placeholder.
1533 Inst.addOperand(MCOperand::CreateImm(0));
1534 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1535 ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1536 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1537 return true;
1538 }
1539
1540 /// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1541 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1542 /// when they refer multiple MIOperands inside a single one.
1543 bool ARMAsmParser::
CvtLdWriteBackRegAddrMode3(MCInst & Inst,unsigned Opcode,const SmallVectorImpl<MCParsedAsmOperand * > & Operands)1544 CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1545 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1546 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1547
1548 // Create a writeback register dummy placeholder.
1549 Inst.addOperand(MCOperand::CreateImm(0));
1550
1551 ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1552 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1553 return true;
1554 }
1555
1556 /// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1557 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
1558 /// when they refer multiple MIOperands inside a single one.
1559 bool ARMAsmParser::
CvtStWriteBackRegAddrMode3(MCInst & Inst,unsigned Opcode,const SmallVectorImpl<MCParsedAsmOperand * > & Operands)1560 CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1561 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1562 // Create a writeback register dummy placeholder.
1563 Inst.addOperand(MCOperand::CreateImm(0));
1564 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1565 ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1566 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1567 return true;
1568 }
1569
1570 /// Parse an ARM memory expression, return false if successful else return true
1571 /// or an error. The first token must be a '[' when called.
1572 ///
1573 /// TODO Only preindexing and postindexing addressing are started, unindexed
1574 /// with option, etc are still to do.
1575 bool ARMAsmParser::
ParseMemory(SmallVectorImpl<MCParsedAsmOperand * > & Operands,ARMII::AddrMode AddrMode=ARMII::AddrModeNone)1576 ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1577 ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1578 SMLoc S, E;
1579 assert(Parser.getTok().is(AsmToken::LBrac) &&
1580 "Token is not a Left Bracket");
1581 S = Parser.getTok().getLoc();
1582 Parser.Lex(); // Eat left bracket token.
1583
1584 const AsmToken &BaseRegTok = Parser.getTok();
1585 if (BaseRegTok.isNot(AsmToken::Identifier)) {
1586 Error(BaseRegTok.getLoc(), "register expected");
1587 return true;
1588 }
1589 int BaseRegNum = TryParseRegister();
1590 if (BaseRegNum == -1) {
1591 Error(BaseRegTok.getLoc(), "register expected");
1592 return true;
1593 }
1594
1595 // The next token must either be a comma or a closing bracket.
1596 const AsmToken &Tok = Parser.getTok();
1597 if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
1598 return true;
1599
1600 bool Preindexed = false;
1601 bool Postindexed = false;
1602 bool OffsetIsReg = false;
1603 bool Negative = false;
1604 bool Writeback = false;
1605 ARMOperand *WBOp = 0;
1606 int OffsetRegNum = -1;
1607 bool OffsetRegShifted = false;
1608 enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
1609 const MCExpr *ShiftAmount = 0;
1610 const MCExpr *Offset = 0;
1611
1612 // First look for preindexed address forms, that is after the "[Rn" we now
1613 // have to see if the next token is a comma.
1614 if (Tok.is(AsmToken::Comma)) {
1615 Preindexed = true;
1616 Parser.Lex(); // Eat comma token.
1617
1618 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1619 Offset, OffsetIsReg, OffsetRegNum, E))
1620 return true;
1621 const AsmToken &RBracTok = Parser.getTok();
1622 if (RBracTok.isNot(AsmToken::RBrac)) {
1623 Error(RBracTok.getLoc(), "']' expected");
1624 return true;
1625 }
1626 E = RBracTok.getLoc();
1627 Parser.Lex(); // Eat right bracket token.
1628
1629 const AsmToken &ExclaimTok = Parser.getTok();
1630 if (ExclaimTok.is(AsmToken::Exclaim)) {
1631 // None of addrmode3 instruction uses "!"
1632 if (AddrMode == ARMII::AddrMode3)
1633 return true;
1634
1635 WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
1636 ExclaimTok.getLoc());
1637 Writeback = true;
1638 Parser.Lex(); // Eat exclaim token
1639 } else { // In addressing mode 2, pre-indexed mode always end with "!"
1640 if (AddrMode == ARMII::AddrMode2)
1641 Preindexed = false;
1642 }
1643 } else {
1644 // The "[Rn" we have so far was not followed by a comma.
1645
1646 // If there's anything other than the right brace, this is a post indexing
1647 // addressing form.
1648 E = Tok.getLoc();
1649 Parser.Lex(); // Eat right bracket token.
1650
1651 const AsmToken &NextTok = Parser.getTok();
1652
1653 if (NextTok.isNot(AsmToken::EndOfStatement)) {
1654 Postindexed = true;
1655 Writeback = true;
1656
1657 if (NextTok.isNot(AsmToken::Comma)) {
1658 Error(NextTok.getLoc(), "',' expected");
1659 return true;
1660 }
1661
1662 Parser.Lex(); // Eat comma token.
1663
1664 if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
1665 ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1666 E))
1667 return true;
1668 }
1669 }
1670
1671 // Force Offset to exist if used.
1672 if (!OffsetIsReg) {
1673 if (!Offset)
1674 Offset = MCConstantExpr::Create(0, getContext());
1675 } else {
1676 if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1677 Error(E, "shift amount not supported");
1678 return true;
1679 }
1680 }
1681
1682 Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1683 Offset, OffsetRegNum, OffsetRegShifted,
1684 ShiftType, ShiftAmount, Preindexed,
1685 Postindexed, Negative, Writeback, S, E));
1686 if (WBOp)
1687 Operands.push_back(WBOp);
1688
1689 return false;
1690 }
1691
1692 /// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
1693 /// we will parse the following (were +/- means that a plus or minus is
1694 /// optional):
1695 /// +/-Rm
1696 /// +/-Rm, shift
1697 /// #offset
1698 /// we return false on success or an error otherwise.
ParseMemoryOffsetReg(bool & Negative,bool & OffsetRegShifted,enum ARM_AM::ShiftOpc & ShiftType,const MCExpr * & ShiftAmount,const MCExpr * & Offset,bool & OffsetIsReg,int & OffsetRegNum,SMLoc & E)1699 bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1700 bool &OffsetRegShifted,
1701 enum ARM_AM::ShiftOpc &ShiftType,
1702 const MCExpr *&ShiftAmount,
1703 const MCExpr *&Offset,
1704 bool &OffsetIsReg,
1705 int &OffsetRegNum,
1706 SMLoc &E) {
1707 Negative = false;
1708 OffsetRegShifted = false;
1709 OffsetIsReg = false;
1710 OffsetRegNum = -1;
1711 const AsmToken &NextTok = Parser.getTok();
1712 E = NextTok.getLoc();
1713 if (NextTok.is(AsmToken::Plus))
1714 Parser.Lex(); // Eat plus token.
1715 else if (NextTok.is(AsmToken::Minus)) {
1716 Negative = true;
1717 Parser.Lex(); // Eat minus token
1718 }
1719 // See if there is a register following the "[Rn," or "[Rn]," we have so far.
1720 const AsmToken &OffsetRegTok = Parser.getTok();
1721 if (OffsetRegTok.is(AsmToken::Identifier)) {
1722 SMLoc CurLoc = OffsetRegTok.getLoc();
1723 OffsetRegNum = TryParseRegister();
1724 if (OffsetRegNum != -1) {
1725 OffsetIsReg = true;
1726 E = CurLoc;
1727 }
1728 }
1729
1730 // If we parsed a register as the offset then there can be a shift after that.
1731 if (OffsetRegNum != -1) {
1732 // Look for a comma then a shift
1733 const AsmToken &Tok = Parser.getTok();
1734 if (Tok.is(AsmToken::Comma)) {
1735 Parser.Lex(); // Eat comma token.
1736
1737 const AsmToken &Tok = Parser.getTok();
1738 if (ParseShift(ShiftType, ShiftAmount, E))
1739 return Error(Tok.getLoc(), "shift expected");
1740 OffsetRegShifted = true;
1741 }
1742 }
1743 else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
1744 // Look for #offset following the "[Rn," or "[Rn],"
1745 const AsmToken &HashTok = Parser.getTok();
1746 if (HashTok.isNot(AsmToken::Hash))
1747 return Error(HashTok.getLoc(), "'#' expected");
1748
1749 Parser.Lex(); // Eat hash token.
1750
1751 if (getParser().ParseExpression(Offset))
1752 return true;
1753 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1754 }
1755 return false;
1756 }
1757
1758 /// ParseShift as one of these two:
1759 /// ( lsl | lsr | asr | ror ) , # shift_amount
1760 /// rrx
1761 /// and returns true if it parses a shift otherwise it returns false.
ParseShift(ARM_AM::ShiftOpc & St,const MCExpr * & ShiftAmount,SMLoc & E)1762 bool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
1763 const MCExpr *&ShiftAmount, SMLoc &E) {
1764 const AsmToken &Tok = Parser.getTok();
1765 if (Tok.isNot(AsmToken::Identifier))
1766 return true;
1767 StringRef ShiftName = Tok.getString();
1768 if (ShiftName == "lsl" || ShiftName == "LSL")
1769 St = ARM_AM::lsl;
1770 else if (ShiftName == "lsr" || ShiftName == "LSR")
1771 St = ARM_AM::lsr;
1772 else if (ShiftName == "asr" || ShiftName == "ASR")
1773 St = ARM_AM::asr;
1774 else if (ShiftName == "ror" || ShiftName == "ROR")
1775 St = ARM_AM::ror;
1776 else if (ShiftName == "rrx" || ShiftName == "RRX")
1777 St = ARM_AM::rrx;
1778 else
1779 return true;
1780 Parser.Lex(); // Eat shift type token.
1781
1782 // Rrx stands alone.
1783 if (St == ARM_AM::rrx)
1784 return false;
1785
1786 // Otherwise, there must be a '#' and a shift amount.
1787 const AsmToken &HashTok = Parser.getTok();
1788 if (HashTok.isNot(AsmToken::Hash))
1789 return Error(HashTok.getLoc(), "'#' expected");
1790 Parser.Lex(); // Eat hash token.
1791
1792 if (getParser().ParseExpression(ShiftAmount))
1793 return true;
1794
1795 return false;
1796 }
1797
1798 /// Parse a arm instruction operand. For now this parses the operand regardless
1799 /// of the mnemonic.
ParseOperand(SmallVectorImpl<MCParsedAsmOperand * > & Operands,StringRef Mnemonic)1800 bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1801 StringRef Mnemonic) {
1802 SMLoc S, E;
1803
1804 // Check if the current operand has a custom associated parser, if so, try to
1805 // custom parse the operand, or fallback to the general approach.
1806 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1807 if (ResTy == MatchOperand_Success)
1808 return false;
1809 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1810 // there was a match, but an error occurred, in which case, just return that
1811 // the operand parsing failed.
1812 if (ResTy == MatchOperand_ParseFail)
1813 return true;
1814
1815 switch (getLexer().getKind()) {
1816 default:
1817 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1818 return true;
1819 case AsmToken::Identifier: {
1820 if (!TryParseRegisterWithWriteBack(Operands))
1821 return false;
1822 int Res = TryParseShiftRegister(Operands);
1823 if (Res == 0) // success
1824 return false;
1825 else if (Res == -1) // irrecoverable error
1826 return true;
1827
1828 // Fall though for the Identifier case that is not a register or a
1829 // special name.
1830 }
1831 case AsmToken::Integer: // things like 1f and 2b as a branch targets
1832 case AsmToken::Dot: { // . as a branch target
1833 // This was not a register so parse other operands that start with an
1834 // identifier (like labels) as expressions and create them as immediates.
1835 const MCExpr *IdVal;
1836 S = Parser.getTok().getLoc();
1837 if (getParser().ParseExpression(IdVal))
1838 return true;
1839 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1840 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
1841 return false;
1842 }
1843 case AsmToken::LBrac:
1844 return ParseMemory(Operands);
1845 case AsmToken::LCurly:
1846 return ParseRegisterList(Operands);
1847 case AsmToken::Hash:
1848 // #42 -> immediate.
1849 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1850 S = Parser.getTok().getLoc();
1851 Parser.Lex();
1852 const MCExpr *ImmVal;
1853 if (getParser().ParseExpression(ImmVal))
1854 return true;
1855 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1856 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
1857 return false;
1858 case AsmToken::Colon: {
1859 // ":lower16:" and ":upper16:" expression prefixes
1860 // FIXME: Check it's an expression prefix,
1861 // e.g. (FOO - :lower16:BAR) isn't legal.
1862 ARMMCExpr::VariantKind RefKind;
1863 if (ParsePrefix(RefKind))
1864 return true;
1865
1866 const MCExpr *SubExprVal;
1867 if (getParser().ParseExpression(SubExprVal))
1868 return true;
1869
1870 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
1871 getContext());
1872 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1873 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
1874 return false;
1875 }
1876 }
1877 }
1878
1879 // ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
1880 // :lower16: and :upper16:.
ParsePrefix(ARMMCExpr::VariantKind & RefKind)1881 bool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
1882 RefKind = ARMMCExpr::VK_ARM_None;
1883
1884 // :lower16: and :upper16: modifiers
1885 assert(getLexer().is(AsmToken::Colon) && "expected a :");
1886 Parser.Lex(); // Eat ':'
1887
1888 if (getLexer().isNot(AsmToken::Identifier)) {
1889 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
1890 return true;
1891 }
1892
1893 StringRef IDVal = Parser.getTok().getIdentifier();
1894 if (IDVal == "lower16") {
1895 RefKind = ARMMCExpr::VK_ARM_LO16;
1896 } else if (IDVal == "upper16") {
1897 RefKind = ARMMCExpr::VK_ARM_HI16;
1898 } else {
1899 Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
1900 return true;
1901 }
1902 Parser.Lex();
1903
1904 if (getLexer().isNot(AsmToken::Colon)) {
1905 Error(Parser.getTok().getLoc(), "unexpected token after prefix");
1906 return true;
1907 }
1908 Parser.Lex(); // Eat the last ':'
1909 return false;
1910 }
1911
1912 const MCExpr *
ApplyPrefixToExpr(const MCExpr * E,MCSymbolRefExpr::VariantKind Variant)1913 ARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
1914 MCSymbolRefExpr::VariantKind Variant) {
1915 // Recurse over the given expression, rebuilding it to apply the given variant
1916 // to the leftmost symbol.
1917 if (Variant == MCSymbolRefExpr::VK_None)
1918 return E;
1919
1920 switch (E->getKind()) {
1921 case MCExpr::Target:
1922 llvm_unreachable("Can't handle target expr yet");
1923 case MCExpr::Constant:
1924 llvm_unreachable("Can't handle lower16/upper16 of constant yet");
1925
1926 case MCExpr::SymbolRef: {
1927 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1928
1929 if (SRE->getKind() != MCSymbolRefExpr::VK_None)
1930 return 0;
1931
1932 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
1933 }
1934
1935 case MCExpr::Unary:
1936 llvm_unreachable("Can't handle unary expressions yet");
1937
1938 case MCExpr::Binary: {
1939 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1940 const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
1941 const MCExpr *RHS = BE->getRHS();
1942 if (!LHS)
1943 return 0;
1944
1945 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
1946 }
1947 }
1948
1949 assert(0 && "Invalid expression kind!");
1950 return 0;
1951 }
1952
1953 /// \brief Given a mnemonic, split out possible predication code and carry
1954 /// setting letters to form a canonical mnemonic and flags.
1955 //
1956 // FIXME: Would be nice to autogen this.
SplitMnemonic(StringRef Mnemonic,unsigned & PredicationCode,bool & CarrySetting,unsigned & ProcessorIMod)1957 StringRef ARMAsmParser::SplitMnemonic(StringRef Mnemonic,
1958 unsigned &PredicationCode,
1959 bool &CarrySetting,
1960 unsigned &ProcessorIMod) {
1961 PredicationCode = ARMCC::AL;
1962 CarrySetting = false;
1963 ProcessorIMod = 0;
1964
1965 // Ignore some mnemonics we know aren't predicated forms.
1966 //
1967 // FIXME: Would be nice to autogen this.
1968 if ((Mnemonic == "movs" && isThumb()) ||
1969 Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" ||
1970 Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
1971 Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" ||
1972 Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" ||
1973 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" ||
1974 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" ||
1975 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
1976 return Mnemonic;
1977
1978 // First, split out any predication code. Ignore mnemonics we know aren't
1979 // predicated but do have a carry-set and so weren't caught above.
1980 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs") {
1981 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
1982 .Case("eq", ARMCC::EQ)
1983 .Case("ne", ARMCC::NE)
1984 .Case("hs", ARMCC::HS)
1985 .Case("cs", ARMCC::HS)
1986 .Case("lo", ARMCC::LO)
1987 .Case("cc", ARMCC::LO)
1988 .Case("mi", ARMCC::MI)
1989 .Case("pl", ARMCC::PL)
1990 .Case("vs", ARMCC::VS)
1991 .Case("vc", ARMCC::VC)
1992 .Case("hi", ARMCC::HI)
1993 .Case("ls", ARMCC::LS)
1994 .Case("ge", ARMCC::GE)
1995 .Case("lt", ARMCC::LT)
1996 .Case("gt", ARMCC::GT)
1997 .Case("le", ARMCC::LE)
1998 .Case("al", ARMCC::AL)
1999 .Default(~0U);
2000 if (CC != ~0U) {
2001 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
2002 PredicationCode = CC;
2003 }
2004 }
2005
2006 // Next, determine if we have a carry setting bit. We explicitly ignore all
2007 // the instructions we know end in 's'.
2008 if (Mnemonic.endswith("s") &&
2009 !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
2010 Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
2011 Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
2012 Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
2013 Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) {
2014 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
2015 CarrySetting = true;
2016 }
2017
2018 // The "cps" instruction can have a interrupt mode operand which is glued into
2019 // the mnemonic. Check if this is the case, split it and parse the imod op
2020 if (Mnemonic.startswith("cps")) {
2021 // Split out any imod code.
2022 unsigned IMod =
2023 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2024 .Case("ie", ARM_PROC::IE)
2025 .Case("id", ARM_PROC::ID)
2026 .Default(~0U);
2027 if (IMod != ~0U) {
2028 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2029 ProcessorIMod = IMod;
2030 }
2031 }
2032
2033 return Mnemonic;
2034 }
2035
2036 /// \brief Given a canonical mnemonic, determine if the instruction ever allows
2037 /// inclusion of carry set or predication code operands.
2038 //
2039 // FIXME: It would be nice to autogen this.
2040 void ARMAsmParser::
GetMnemonicAcceptInfo(StringRef Mnemonic,bool & CanAcceptCarrySet,bool & CanAcceptPredicationCode)2041 GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
2042 bool &CanAcceptPredicationCode) {
2043 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
2044 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
2045 Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
2046 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
2047 Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
2048 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
2049 Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
2050 Mnemonic == "eor" || Mnemonic == "smlal" ||
2051 (Mnemonic == "mov" && !isThumbOne())) {
2052 CanAcceptCarrySet = true;
2053 } else {
2054 CanAcceptCarrySet = false;
2055 }
2056
2057 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
2058 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
2059 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
2060 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
2061 Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
2062 Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
2063 CanAcceptPredicationCode = false;
2064 } else {
2065 CanAcceptPredicationCode = true;
2066 }
2067
2068 if (isThumb())
2069 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
2070 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
2071 CanAcceptPredicationCode = false;
2072 }
2073
2074 /// Parse an arm instruction mnemonic followed by its operands.
ParseInstruction(StringRef Name,SMLoc NameLoc,SmallVectorImpl<MCParsedAsmOperand * > & Operands)2075 bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
2076 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2077 // Create the leading tokens for the mnemonic, split by '.' characters.
2078 size_t Start = 0, Next = Name.find('.');
2079 StringRef Mnemonic = Name.slice(Start, Next);
2080
2081 // Split out the predication code and carry setting flag from the mnemonic.
2082 unsigned PredicationCode;
2083 unsigned ProcessorIMod;
2084 bool CarrySetting;
2085 Mnemonic = SplitMnemonic(Mnemonic, PredicationCode, CarrySetting,
2086 ProcessorIMod);
2087
2088 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
2089
2090 // FIXME: This is all a pretty gross hack. We should automatically handle
2091 // optional operands like this via tblgen.
2092
2093 // Next, add the CCOut and ConditionCode operands, if needed.
2094 //
2095 // For mnemonics which can ever incorporate a carry setting bit or predication
2096 // code, our matching model involves us always generating CCOut and
2097 // ConditionCode operands to match the mnemonic "as written" and then we let
2098 // the matcher deal with finding the right instruction or generating an
2099 // appropriate error.
2100 bool CanAcceptCarrySet, CanAcceptPredicationCode;
2101 GetMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
2102
2103 // If we had a carry-set on an instruction that can't do that, issue an
2104 // error.
2105 if (!CanAcceptCarrySet && CarrySetting) {
2106 Parser.EatToEndOfStatement();
2107 return Error(NameLoc, "instruction '" + Mnemonic +
2108 "' can not set flags, but 's' suffix specified");
2109 }
2110
2111 // Add the carry setting operand, if necessary.
2112 //
2113 // FIXME: It would be awesome if we could somehow invent a location such that
2114 // match errors on this operand would print a nice diagnostic about how the
2115 // 's' character in the mnemonic resulted in a CCOut operand.
2116 if (CanAcceptCarrySet)
2117 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
2118 NameLoc));
2119
2120 // Add the predication code operand, if necessary.
2121 if (CanAcceptPredicationCode) {
2122 Operands.push_back(ARMOperand::CreateCondCode(
2123 ARMCC::CondCodes(PredicationCode), NameLoc));
2124 } else {
2125 // This mnemonic can't ever accept a predication code, but the user wrote
2126 // one (or misspelled another mnemonic).
2127
2128 // FIXME: Issue a nice error.
2129 }
2130
2131 // Add the processor imod operand, if necessary.
2132 if (ProcessorIMod) {
2133 Operands.push_back(ARMOperand::CreateImm(
2134 MCConstantExpr::Create(ProcessorIMod, getContext()),
2135 NameLoc, NameLoc));
2136 } else {
2137 // This mnemonic can't ever accept a imod, but the user wrote
2138 // one (or misspelled another mnemonic).
2139
2140 // FIXME: Issue a nice error.
2141 }
2142
2143 // Add the remaining tokens in the mnemonic.
2144 while (Next != StringRef::npos) {
2145 Start = Next;
2146 Next = Name.find('.', Start + 1);
2147 StringRef ExtraToken = Name.slice(Start, Next);
2148
2149 Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
2150 }
2151
2152 // Read the remaining operands.
2153 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2154 // Read the first operand.
2155 if (ParseOperand(Operands, Mnemonic)) {
2156 Parser.EatToEndOfStatement();
2157 return true;
2158 }
2159
2160 while (getLexer().is(AsmToken::Comma)) {
2161 Parser.Lex(); // Eat the comma.
2162
2163 // Parse and remember the operand.
2164 if (ParseOperand(Operands, Mnemonic)) {
2165 Parser.EatToEndOfStatement();
2166 return true;
2167 }
2168 }
2169 }
2170
2171 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2172 Parser.EatToEndOfStatement();
2173 return TokError("unexpected token in argument list");
2174 }
2175
2176 Parser.Lex(); // Consume the EndOfStatement
2177
2178
2179 // The 'mov' mnemonic is special. One variant has a cc_out operand, while
2180 // another does not. Specifically, the MOVW instruction does not. So we
2181 // special case it here and remove the defaulted (non-setting) cc_out
2182 // operand if that's the instruction we're trying to match.
2183 //
2184 // We do this post-processing of the explicit operands rather than just
2185 // conditionally adding the cc_out in the first place because we need
2186 // to check the type of the parsed immediate operand.
2187 if (Mnemonic == "mov" && Operands.size() > 4 &&
2188 !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
2189 static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
2190 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) {
2191 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
2192 Operands.erase(Operands.begin() + 1);
2193 delete Op;
2194 }
2195
2196
2197
2198 return false;
2199 }
2200
2201 bool ARMAsmParser::
MatchAndEmitInstruction(SMLoc IDLoc,SmallVectorImpl<MCParsedAsmOperand * > & Operands,MCStreamer & Out)2202 MatchAndEmitInstruction(SMLoc IDLoc,
2203 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2204 MCStreamer &Out) {
2205 MCInst Inst;
2206 unsigned ErrorInfo;
2207 MatchResultTy MatchResult;
2208 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2209 switch (MatchResult) {
2210 case Match_Success:
2211 Out.EmitInstruction(Inst);
2212 return false;
2213 case Match_MissingFeature:
2214 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2215 return true;
2216 case Match_InvalidOperand: {
2217 SMLoc ErrorLoc = IDLoc;
2218 if (ErrorInfo != ~0U) {
2219 if (ErrorInfo >= Operands.size())
2220 return Error(IDLoc, "too few operands for instruction");
2221
2222 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2223 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2224 }
2225
2226 return Error(ErrorLoc, "invalid operand for instruction");
2227 }
2228 case Match_MnemonicFail:
2229 return Error(IDLoc, "unrecognized instruction mnemonic");
2230 case Match_ConversionFail:
2231 return Error(IDLoc, "unable to convert operands to instruction");
2232 }
2233
2234 llvm_unreachable("Implement any new match types added!");
2235 return true;
2236 }
2237
2238 /// ParseDirective parses the arm specific directives
ParseDirective(AsmToken DirectiveID)2239 bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2240 StringRef IDVal = DirectiveID.getIdentifier();
2241 if (IDVal == ".word")
2242 return ParseDirectiveWord(4, DirectiveID.getLoc());
2243 else if (IDVal == ".thumb")
2244 return ParseDirectiveThumb(DirectiveID.getLoc());
2245 else if (IDVal == ".thumb_func")
2246 return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2247 else if (IDVal == ".code")
2248 return ParseDirectiveCode(DirectiveID.getLoc());
2249 else if (IDVal == ".syntax")
2250 return ParseDirectiveSyntax(DirectiveID.getLoc());
2251 return true;
2252 }
2253
2254 /// ParseDirectiveWord
2255 /// ::= .word [ expression (, expression)* ]
ParseDirectiveWord(unsigned Size,SMLoc L)2256 bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2257 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2258 for (;;) {
2259 const MCExpr *Value;
2260 if (getParser().ParseExpression(Value))
2261 return true;
2262
2263 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2264
2265 if (getLexer().is(AsmToken::EndOfStatement))
2266 break;
2267
2268 // FIXME: Improve diagnostic.
2269 if (getLexer().isNot(AsmToken::Comma))
2270 return Error(L, "unexpected token in directive");
2271 Parser.Lex();
2272 }
2273 }
2274
2275 Parser.Lex();
2276 return false;
2277 }
2278
2279 /// ParseDirectiveThumb
2280 /// ::= .thumb
ParseDirectiveThumb(SMLoc L)2281 bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2282 if (getLexer().isNot(AsmToken::EndOfStatement))
2283 return Error(L, "unexpected token in directive");
2284 Parser.Lex();
2285
2286 // TODO: set thumb mode
2287 // TODO: tell the MC streamer the mode
2288 // getParser().getStreamer().Emit???();
2289 return false;
2290 }
2291
2292 /// ParseDirectiveThumbFunc
2293 /// ::= .thumbfunc symbol_name
ParseDirectiveThumbFunc(SMLoc L)2294 bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
2295 const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
2296 bool isMachO = MAI.hasSubsectionsViaSymbols();
2297 StringRef Name;
2298
2299 // Darwin asm has function name after .thumb_func direction
2300 // ELF doesn't
2301 if (isMachO) {
2302 const AsmToken &Tok = Parser.getTok();
2303 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
2304 return Error(L, "unexpected token in .thumb_func directive");
2305 Name = Tok.getString();
2306 Parser.Lex(); // Consume the identifier token.
2307 }
2308
2309 if (getLexer().isNot(AsmToken::EndOfStatement))
2310 return Error(L, "unexpected token in directive");
2311 Parser.Lex();
2312
2313 // FIXME: assuming function name will be the line following .thumb_func
2314 if (!isMachO) {
2315 Name = Parser.getTok().getString();
2316 }
2317
2318 // Mark symbol as a thumb symbol.
2319 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2320 getParser().getStreamer().EmitThumbFunc(Func);
2321 return false;
2322 }
2323
2324 /// ParseDirectiveSyntax
2325 /// ::= .syntax unified | divided
ParseDirectiveSyntax(SMLoc L)2326 bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
2327 const AsmToken &Tok = Parser.getTok();
2328 if (Tok.isNot(AsmToken::Identifier))
2329 return Error(L, "unexpected token in .syntax directive");
2330 StringRef Mode = Tok.getString();
2331 if (Mode == "unified" || Mode == "UNIFIED")
2332 Parser.Lex();
2333 else if (Mode == "divided" || Mode == "DIVIDED")
2334 return Error(L, "'.syntax divided' arm asssembly not supported");
2335 else
2336 return Error(L, "unrecognized syntax mode in .syntax directive");
2337
2338 if (getLexer().isNot(AsmToken::EndOfStatement))
2339 return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2340 Parser.Lex();
2341
2342 // TODO tell the MC streamer the mode
2343 // getParser().getStreamer().Emit???();
2344 return false;
2345 }
2346
2347 /// ParseDirectiveCode
2348 /// ::= .code 16 | 32
ParseDirectiveCode(SMLoc L)2349 bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
2350 const AsmToken &Tok = Parser.getTok();
2351 if (Tok.isNot(AsmToken::Integer))
2352 return Error(L, "unexpected token in .code directive");
2353 int64_t Val = Parser.getTok().getIntVal();
2354 if (Val == 16)
2355 Parser.Lex();
2356 else if (Val == 32)
2357 Parser.Lex();
2358 else
2359 return Error(L, "invalid operand to .code directive");
2360
2361 if (getLexer().isNot(AsmToken::EndOfStatement))
2362 return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2363 Parser.Lex();
2364
2365 if (Val == 16) {
2366 if (!isThumb())
2367 SwitchMode();
2368 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2369 } else {
2370 if (isThumb())
2371 SwitchMode();
2372 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2373 }
2374
2375 return false;
2376 }
2377
2378 extern "C" void LLVMInitializeARMAsmLexer();
2379
2380 /// Force static initialization.
LLVMInitializeARMAsmParser()2381 extern "C" void LLVMInitializeARMAsmParser() {
2382 RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2383 RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
2384 LLVMInitializeARMAsmLexer();
2385 }
2386
2387 #define GET_REGISTER_MATCHER
2388 #define GET_MATCHER_IMPLEMENTATION
2389 #include "ARMGenAsmMatcher.inc"
2390