ARMAsmParser.cpp revision b3cb6967949493a2e1b10d015ac08b746736764e
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 { 1098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 110cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 1118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 1128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 114a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 115a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 116762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 117a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 124a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 125a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 13099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback; 131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 133cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby struct { 134cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 135cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 136762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // This is for all forms of ARM address expressions 138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned OffsetRegNum; // used when OffsetIsReg is true 1419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *Offset; // used when OffsetIsReg is false 142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 1439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType ShiftType; // used when OffsetRegShifted is true 1449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby unsigned 1459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted : 1, // only used when OffsetIsReg is true 1469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Preindexed : 1, 1479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Postindexed : 1, 1489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg : 1, 1499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative : 1, // only used when OffsetIsReg is true 1509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback : 1; 151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 152a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 154762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 155762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(KindTy K, SMLoc S, SMLoc E) 156762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan : Kind(K), StartLoc(S), EndLoc(E) {} 157762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 158762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 1638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 1648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 1658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 166762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 1678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 168762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 169762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 173762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 177762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 178762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 179762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 183762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 184762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 185a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 1898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 1908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 192a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Register && "Invalid access!"); 198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Reg.RegNum; 199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 201cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 202cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 203cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 204cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 205cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 2068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 2078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool isReg() const { return Kind == Register; } 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isToken() const {return Kind == Token; } 2133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 2153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar // Add as immediates when possible. 2163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 2183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 2193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 2203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 2238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 2248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 2258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 2268462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 227a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 228a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 229a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 230a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 2333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 2343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 2353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 237b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar virtual void dump(raw_ostream &OS) const {} 238b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 239762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateToken(OwningPtr<ARMOperand> &Op, StringRef Str, 240762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S) { 241762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 242762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Token; 243762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 245762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 246762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 249762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateReg(OwningPtr<ARMOperand> &Op, unsigned RegNum, 250762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool Writeback, SMLoc S, SMLoc E) { 251762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 252762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Register; 253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.Writeback = Writeback; 255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 258a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 259a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 260762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateImm(OwningPtr<ARMOperand> &Op, const MCExpr *Val, 261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, SMLoc E) { 262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Immediate; 264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 268cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 269cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateMem(OwningPtr<ARMOperand> &Op, 271762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan unsigned BaseRegNum, bool OffsetIsReg, 272762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *Offset, unsigned OffsetRegNum, 273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool OffsetRegShifted, enum ShiftType ShiftType, 274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *ShiftAmount, bool Preindexed, 275762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool Postindexed, bool Negative, bool Writeback, 276762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, SMLoc E) { 277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Memory; 279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 281762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Offset = Offset; 282762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegNum = OffsetRegNum; 283762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 284762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 294a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 295a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 3003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 3013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 3033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 3053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 3079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and if it is a register name a Reg operand is created, the token is eaten 3089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and false is returned. Else true is returned and no token is eaten. 3099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO this is likely to change to allow different register types and or to 3109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// parse for a specific register type. 311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::MaybeParseRegister 312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan (OwningPtr<ARMOperand> &Op, bool ParseWriteBack) { 313762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 31418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 319d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum; 320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby RegNum = MatchRegisterName(Tok.getString()); 322d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 324762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 325762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Tok.getLoc(); 326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 327b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 328762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 329762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Parser.getTok().getLoc(); 330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback = false; 3329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ParseWriteBack) { 33318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 3349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 335762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 3369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback = true; 337b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 3389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 33999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 34099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 341762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateReg(Op, RegNum, Writeback, S, E); 34299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 344a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 345a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a register list, return false if successful else return true or an 3479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// error. The first token must be a '{' when called. 348762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) { 349762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 35018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 351cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby "Token is not an Left Curly Brace"); 352762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 353b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 354d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 35518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 356d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 357d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 358d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 359d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 360d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 361d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 362b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 363d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby unsigned RegList = 1 << RegNum; 364d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 365d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int HighRegNum = RegNum; 366d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby // TODO ranges like "{Rn-Rm}" 36718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan while (Parser.getTok().is(AsmToken::Comma)) { 368b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 369d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 37018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 371d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 372d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 373d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 374d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 375d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 376d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 377d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 378d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegList & (1 << RegNum)) 379d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register duplicated in register list"); 380d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (RegNum <= HighRegNum) 381d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register not in ascending order in register list"); 382d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby RegList |= 1 << RegNum; 383d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby HighRegNum = RegNum; 384d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 385b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 386d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby } 38718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 388d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RCurlyTok.isNot(AsmToken::RCurly)) 389d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RCurlyTok.getLoc(), "'}' expected"); 390762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RCurlyTok.getLoc(); 391b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 392d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 393d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return false; 394d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 395d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 3969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true 3979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 3989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 3999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 400762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand> &Op) { 401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 40218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 4036bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby "Token is not an Left Bracket"); 404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 405b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 406a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 40718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 408a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (BaseRegTok.isNot(AsmToken::Identifier)) 409a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 4109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (MaybeParseRegister(Op, false)) 411a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 412762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int BaseRegNum = Op->getReg(); 413a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 414a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 415a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 416a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 417a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 418a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 419a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 4219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 42218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 423a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 424a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 425b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 4279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 428a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 429a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 430a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 4319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Offset, OffsetIsReg, OffsetRegNum, E)) 4339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 43418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 435a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (RBracTok.isNot(AsmToken::RBrac)) 436a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(RBracTok.getLoc(), "']' expected"); 437762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 438b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 44018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 442762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 444b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 446762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 447762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegShifted, ShiftType, ShiftAmount, 448762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Preindexed, Postindexed, Negative, Writeback, S, E); 449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // The "[Rn" we have so far was not followed by a comma. 452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 4539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // This is a post indexing addressing forms, that is a ']' follows after 4549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // the "[Rn". 455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Postindexed = true; 456a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 457762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 458b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 459a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 460e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 461a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 462a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 463a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 464a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 465a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 46618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 467e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 468e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::Comma)) 4693472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(NextTok.getLoc(), "',' expected"); 470b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E)) 4749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 476e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegShifted, ShiftType, ShiftAmount, 479762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Preindexed, Postindexed, Negative, Writeback, S, E); 480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 481a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 482a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 485a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 4879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 4889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 4899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 4909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 4919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 4929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 4939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 494762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 4959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 4969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 4979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 4989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 500762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 501762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 5029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 5039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 5049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 5059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 50618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 507762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 5089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 509b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 5109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 5119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 512b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 5139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 51518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 5169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 5179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = !MaybeParseRegister(Op, false); 518762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (OffsetIsReg) { 519762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Op->getEndLoc(); 520762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegNum = Op->getReg(); 521762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 5229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 5249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 5259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 52618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 528b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 53018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 531762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 5323472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 5339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 5349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 5379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 53818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 5399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 5409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 541762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 542b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 5439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 5449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 5459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 546762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 5479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 5499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 5509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 551a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 552a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 553a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 555762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseShift(ShiftType &St, 556762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *&ShiftAmount, 557762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 55818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 559a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 560a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 56138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 562a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 5639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 564a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 5659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 566a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 5679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 568a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 5699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 570a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 5719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 572a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 573a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 574b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 575a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 5779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 5789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 579a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 58118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 5829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 5839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 584b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 5859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 5869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 5879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 588a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 589a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 590a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 591a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 5939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 594762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseOperand(OwningPtr<ARMOperand> &Op) { 595762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 596762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 597a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 598a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 5999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (!MaybeParseRegister(Op, true)) 600a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 601515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 602515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 603515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 604762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 605515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 606515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return true; 607762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 608762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateImm(Op, IdVal, S, E); 609515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 610a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 611515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseMemory(Op); 612d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 613515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseRegisterList(Op); 614d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 615079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 616079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 617762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 618b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 619515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 620515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 621cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return true; 622762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 623762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateImm(Op, ImmVal, S, E); 624cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return false; 625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 62618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in operand"); 627a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 628a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 63138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 6329898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 633762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 634762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateToken(Op, Name, NameLoc); 635762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 636762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 637a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 638a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 639a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 640a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 641762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 6429898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 643762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 644a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 645a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 646b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 647a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 648a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 6499898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 650762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 651a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 6539898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 654ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 655ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 656515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 657ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 658ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 659ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 660ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 661515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 662515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 663515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 664515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 665515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 666515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 667515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 668515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 669ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 670ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 671ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 672ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 673ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 674ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 675ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 676ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 677ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 678ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 679ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 680ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 681aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 682ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 683ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 684ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 685ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 686ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 687ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 688ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 689b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 690ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 691ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 692ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 693b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 694ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 695ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 696ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 697515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 698515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 699515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 700515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 701515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 702b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 703515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 704515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 705515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 706515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 707515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 708515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 709515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 710515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 711515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 712515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 71318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 714515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 715515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 71618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier(); 717b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 718515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 719515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 720515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 721b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 722515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 723515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: mark symbol as a thumb symbol 724515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 725515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 726515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 727515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 728515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 729515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 730515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 73118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 732515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 733515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 73438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 73558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 736b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 73758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 738b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 739515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 740515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 742515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 74318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 744b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 745515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 746515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 747515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 748515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 749515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 750515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 751515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 752515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 753515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 75418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 756515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 75718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 75858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 759b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 76058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 761b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 762515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 763515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 764515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 765515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 76618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 767b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 768515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 769515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 770515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 772515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 773515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 77490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 77590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 7769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 777ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 778ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 779ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 78090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 781ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 7823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 7833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 784