ARMAsmParser.cpp revision 3483acabf012b847b13b969ebd9ce5c4d16d9eb7
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h" 113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h" 12c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 15ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 16ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 17ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h" 20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/Compiler.h" 21c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 22762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan#include "llvm/ADT/OwningPtr.h" 23c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 24c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 26ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 27ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbynamespace { 28ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbystruct ARMOperand; 29ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 30a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby// The shift types for register controlled shifts in arm memory addressing 31a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbyenum ShiftType { 32a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsl, 33a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsr, 34a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Asr, 35a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Ror, 36a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Rrx 37a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 38a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 39ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser { 40ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 41d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar TargetMachine &TM; 42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyprivate: 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 52762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool MaybeParseRegister(OwningPtr<ARMOperand> &Op, bool ParseWriteBack); 53a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 54762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseRegisterList(OwningPtr<ARMOperand> &Op); 55d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 56762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseMemory(OwningPtr<ARMOperand> &Op); 57a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 64762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 65762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 67762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); 68a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 69762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseOperand(OwningPtr<ARMOperand> &Op); 70a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 71ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 72ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 73515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 79515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 80515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 81a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 82a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar unsigned ComputeAvailableFeatures(const ARMSubtarget *Subtarget) const; 853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 869898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, 87a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby MCInst &Inst); 88a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 89a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 90a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 92ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 93d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) 94d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar : TargetAsmParser(T), Parser(_Parser), TM(_TM) {} 95ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 9638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 979898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 98ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 99ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 100ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 101ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 102a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 103a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 1047659389d0d4d315d30877592221da6a6f663114aChris Lattnerstruct ARMOperand : public MCParsedAsmOperand { 105762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananprivate: 106762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand() {} 107762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananpublic: 108762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Token, 110a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Register, 111cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 112a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Memory 113a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 114a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 115762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 117a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 121a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 122a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 123a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 124a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 12599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback; 126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 128cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby struct { 129cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 130cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 131762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // This is for all forms of ARM address expressions 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned OffsetRegNum; // used when OffsetIsReg is true 1369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *Offset; // used when OffsetIsReg is false 137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 1389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType ShiftType; // used when OffsetRegShifted is true 1399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby unsigned 1409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted : 1, // only used when OffsetIsReg is true 1419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Preindexed : 1, 1429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Postindexed : 1, 1439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg : 1, 1449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative : 1, // only used when OffsetIsReg is true 1459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback : 1; 146a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 147a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 148a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 149762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 150762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(KindTy K, SMLoc S, SMLoc E) 151762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan : Kind(K), StartLoc(S), EndLoc(E) {} 152762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 153762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 154762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 155762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 156762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 157762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 158762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Tok = o.Tok; 160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 163762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 164762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 165762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 166762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 167762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 168762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 169762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 173762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 177a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 180a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 184a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Register && "Invalid access!"); 185a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Reg.RegNum; 186a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 188cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 189cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 190cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 191cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 192cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 1933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool isReg() const { return Kind == Register; } 196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isToken() const {return Kind == Token; } 1983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 1993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 2003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar // Add as immediates when possible. 2013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 2033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 2043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 2053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 207a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 2133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 2143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 2153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 217762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateToken(OwningPtr<ARMOperand> &Op, StringRef Str, 218762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S) { 219762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 220762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Token; 221762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 222762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 223762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 224762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 226a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 227762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateReg(OwningPtr<ARMOperand> &Op, unsigned RegNum, 228762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool Writeback, SMLoc S, SMLoc E) { 229762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 230762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Register; 231762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 232762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.Writeback = Writeback; 233762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 234762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 235762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 236a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 237a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 238762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateImm(OwningPtr<ARMOperand> &Op, const MCExpr *Val, 239762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, SMLoc E) { 240762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 241762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Immediate; 242762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 243762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 245762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 246cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 247cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 248762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateMem(OwningPtr<ARMOperand> &Op, 249762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan unsigned BaseRegNum, bool OffsetIsReg, 250762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *Offset, unsigned OffsetRegNum, 251762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool OffsetRegShifted, enum ShiftType ShiftType, 252762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *ShiftAmount, bool Preindexed, 253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool Postindexed, bool Negative, bool Writeback, 254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, SMLoc E) { 255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Memory; 257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 259762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Offset = Offset; 260762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegNum = OffsetRegNum; 261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 271a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 275a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2763483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 2783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 2793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 2813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 2833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 2859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and if it is a register name a Reg operand is created, the token is eaten 2869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and false is returned. Else true is returned and no token is eaten. 2879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO this is likely to change to allow different register types and or to 2889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// parse for a specific register type. 289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::MaybeParseRegister 290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan (OwningPtr<ARMOperand> &Op, bool ParseWriteBack) { 291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 29218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 294a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 295a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 297d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum; 298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby RegNum = MatchRegisterName(Tok.getString()); 300d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Tok.getLoc(); 304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 305b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 306762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Parser.getTok().getLoc(); 308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback = false; 3109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ParseWriteBack) { 31118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 3129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 313762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 3149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback = true; 315b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 3169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 31799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 31899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 319762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateReg(Op, RegNum, Writeback, S, E); 32099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a register list, return false if successful else return true or an 3259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// error. The first token must be a '{' when called. 326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) { 327762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 32818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 329cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby "Token is not an Left Curly Brace"); 330762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 331b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 332d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 33318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 334d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 335d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 336d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 337d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 338d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 339d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 340b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 341d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby unsigned RegList = 1 << RegNum; 342d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 343d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int HighRegNum = RegNum; 344d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby // TODO ranges like "{Rn-Rm}" 34518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan while (Parser.getTok().is(AsmToken::Comma)) { 346b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 347d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 34818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 349d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 350d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 351d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 352d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 353d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 354d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 355d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 356d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegList & (1 << RegNum)) 357d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register duplicated in register list"); 358d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (RegNum <= HighRegNum) 359d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register not in ascending order in register list"); 360d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby RegList |= 1 << RegNum; 361d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby HighRegNum = RegNum; 362d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 363b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 364d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby } 36518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 366d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RCurlyTok.isNot(AsmToken::RCurly)) 367d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RCurlyTok.getLoc(), "'}' expected"); 368762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RCurlyTok.getLoc(); 369b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 370d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 371d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return false; 372d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 373d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 3749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true 3759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 3769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 3779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 378762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand> &Op) { 379762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 38018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3816bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby "Token is not an Left Bracket"); 382762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 383b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 384a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 38518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 386a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (BaseRegTok.isNot(AsmToken::Identifier)) 387a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 3889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (MaybeParseRegister(Op, false)) 389a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 390762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int BaseRegNum = Op->getReg(); 391a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 392a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 393a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 394a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 395a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 396a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 397a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 3999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 40018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 401a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 402a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 403b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 4059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 406a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 407a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 408a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 4099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 410762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Offset, OffsetIsReg, OffsetRegNum, E)) 4119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 41218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 413a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (RBracTok.isNot(AsmToken::RBrac)) 414a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(RBracTok.getLoc(), "']' expected"); 415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 416b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 417a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 41818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 419a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 420762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 421a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 422b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 423a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 424762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 425762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegShifted, ShiftType, ShiftAmount, 426762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Preindexed, Postindexed, Negative, Writeback, S, E); 427a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 428a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 429a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // The "[Rn" we have so far was not followed by a comma. 430a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 4319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // This is a post indexing addressing forms, that is a ']' follows after 4329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // the "[Rn". 433a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Postindexed = true; 434a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 436b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 437a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 438e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 440a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 442a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 44418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 445e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 446e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::Comma)) 4473472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(NextTok.getLoc(), "',' expected"); 448b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 450762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 451762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E)) 4529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 453a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 454e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 455762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 456762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegShifted, ShiftType, ShiftAmount, 457762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Preindexed, Postindexed, Negative, Writeback, S, E); 458a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 459a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 461a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 462a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 463a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 4659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 4669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 4679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 4689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 4699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 4709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 4719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 4739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 4749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 4759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 4769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 479762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 4809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 4819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 4829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 4839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 48418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 485762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 4869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 487b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 4889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 4899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 490b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 4919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 4929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 49318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 4949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 4959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = !MaybeParseRegister(Op, false); 496762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (OffsetIsReg) { 497762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Op->getEndLoc(); 498762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegNum = Op->getReg(); 499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 5009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 5029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 5039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 50418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 506b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 50818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 509762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 5103472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 5119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 5129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 5159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 51618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 5179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 5189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 519762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 520b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 5219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 5229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 5239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 524762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 5259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 5279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 5289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 529a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 530a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 531a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 532a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 533762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseShift(ShiftType &St, 534762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *&ShiftAmount, 535762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 53618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 537a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 538a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 53938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 540a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 5419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 5439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 5459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 546a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 5479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 548a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 5499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 550a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 551a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 552b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 553a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 5559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 5569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 557a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 55918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 5609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 5619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 562b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 5639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 5649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 5659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 566a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 567a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 568a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 569a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 5719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 572762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseOperand(OwningPtr<ARMOperand> &Op) { 573762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 574762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 575a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 576a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 5779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (!MaybeParseRegister(Op, true)) 578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 579515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 580515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 581515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 582762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 583515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 584515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return true; 585762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 586762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateImm(Op, IdVal, S, E); 587515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 588a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 589515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseMemory(Op); 590d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 591515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseRegisterList(Op); 592d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 593079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 594079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 595762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 596b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 597515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 598515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 599cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return true; 600762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 601762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateImm(Op, ImmVal, S, E); 602cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return false; 603a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 60418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in operand"); 605a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 60938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 6109898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 611762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 612762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateToken(Op, Name, NameLoc); 613762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 614762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 615a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 619762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 6209898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 621762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 624b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 626a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 6279898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 628762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 630a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 6319898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 632ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 633ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 634515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 635ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 636ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 637ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 638ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 639515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 640515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 641515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 642515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 643515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 644515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 645515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 646515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 647ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 648ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 649ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 650ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 651ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 652ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 653ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 654ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 655ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 656ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 657ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 658ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 659aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 660ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 661ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 662ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 663ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 664ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 665ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 666ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 667b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 668ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 669ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 670ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 671b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 672ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 673ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 674ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 675515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 676515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 677515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 678515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 679515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 680b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 682515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 684515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 685515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 686515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 687515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 688515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 689515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 690515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 69118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 692515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 693515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 69418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier(); 695b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 696515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 697515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 698515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 699b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 700515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 701515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: mark symbol as a thumb symbol 702515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 703515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 704515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 705515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 706515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 707515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 708515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 70918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 710515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 711515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 71238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 71358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 714b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 71558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 716b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 717515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 718515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 719515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 720515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 72118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 722b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 723515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 724515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 725515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 726515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 727515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 728515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 729515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 730515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 731515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 73218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 733515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 734515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 73518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 73658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 737b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 73858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 739b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 740515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 742515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 74418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 745b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 746515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 747515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 748515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 749515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 750515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 751515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 75290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 75390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 7549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 755ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 756ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 757ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 75890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 759ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 7603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 7613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 762