ARMAsmParser.cpp revision 16c7425cff6ac3d0a4a9c56779bdfa91b2e8e863
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/SourceMgr.h" 21fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 22c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 23345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 24c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 26ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 27a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby// The shift types for register controlled shifts in arm memory addressing 28a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbyenum ShiftType { 29a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsl, 30a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsr, 31a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Asr, 32a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Ror, 33a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Rrx 34a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 35a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 363a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner struct ARMOperand; 3816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 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 523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *MaybeParseRegister(bool ParseWriteBack); 53c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner ARMOperand *ParseRegisterList(); 54550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner ARMOperand *ParseMemory(); 55a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 62762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 63762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 65762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); 66a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 67550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner ARMOperand *ParseOperand(); 68a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 69ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 70ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 71515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 72515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 73515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 797036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 807c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 81fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out); 8216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 83a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 84a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 860692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 870692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 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}; 10116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 10216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1033a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 1077659389d0d4d315d30877592221da6a6f663114aChris Lattnerstruct ARMOperand : public MCParsedAsmOperand { 108762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananpublic: 109762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 111cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 1128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 1138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 115a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 117762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 125a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 13199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback; 132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 134cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby struct { 135cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 136cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 13716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // This is for all forms of ARM address expressions 139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 141a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned OffsetRegNum; // used when OffsetIsReg is true 1429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *Offset; // used when OffsetIsReg is false 143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 1449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType ShiftType; // used when OffsetRegShifted is true 1459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby unsigned 1469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted : 1, // only used when OffsetIsReg is true 1479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Preindexed : 1, 1489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Postindexed : 1, 1499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg : 1, 1509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative : 1, // only used when OffsetIsReg is true 1519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback : 1; 152a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 15516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 156762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 157762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 158762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 1618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 1628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 1638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 164762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 1658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 166762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 167762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 168762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 169762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 173762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 177762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 17816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 179762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1848462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 1858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 1868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 190a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 192a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Register && "Invalid access!"); 196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Reg.RegNum; 197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 199cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 200cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 201cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 202cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 203cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 2048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 2053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool isReg() const { return Kind == Register; } 20714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 20814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 2093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 21114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 21214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 21314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 21414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 2163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 2173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 2183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 221345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 2228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 223345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: What belongs here? 224345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(0)); 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 } 23616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 23716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 23814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemMode5() const { 23914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // FIXME: Is this right? What about postindexed and Writeback? 24014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted || 24114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Mem.Preindexed || Mem.Negative) 24214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner return false; 24316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 24414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner return true; 24514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 24616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 24714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 24814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 24916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 25014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 25114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(!Mem.OffsetIsReg && "invalid mode 5 operand"); 25214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner addExpr(Inst, Mem.Offset); 25314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 2543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 255fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar virtual void dump(raw_ostream &OS) const; 256b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 2573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 2583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 259345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 260345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 261345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 2623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 263345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 264345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 2663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 2713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2743a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateReg(unsigned RegNum, bool Writeback, SMLoc S, 2753a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc E) { 2763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.Writeback = Writeback; 279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 2813a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 282a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 2853a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 2893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 290cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 291cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 2923a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, 2933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *Offset, unsigned OffsetRegNum, 2943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool OffsetRegShifted, enum ShiftType ShiftType, 2953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *ShiftAmount, bool Preindexed, 2963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool Postindexed, bool Negative, bool Writeback, 2973a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 2983a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Offset = Offset; 302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegNum = OffsetRegNum; 303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 306762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 31016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 3133a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 31516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3163a69756e392942bc522193f38d7f33958ed3b131Chris Lattnerprivate: 3173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand(KindTy K) : Kind(K) {} 318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 319a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 322fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const { 323fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 324fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 325fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << ARMCondCodeToString(getCondCode()); 326fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 327fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 328fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 329fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 330fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 331fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "<memory>"; 332fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 333fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 334fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "<register " << getReg() << ">"; 335fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 336fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 337fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 338fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 339fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 340fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 3413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3423483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 3433483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 3443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3453483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 3463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 3483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 3503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// and if it is a register name the token is eaten and a Reg operand is created 3513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// and returned. Otherwise return null. 3523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 3539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO this is likely to change to allow different register types and or to 3549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// parse for a specific register type. 3553a69756e392942bc522193f38d7f33958ed3b131Chris LattnerARMOperand *ARMAsmParser::MaybeParseRegister(bool ParseWriteBack) { 356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 35718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 358a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 359a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 360a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 361a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 362d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum; 363a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 364a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby RegNum = MatchRegisterName(Tok.getString()); 365d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 3663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return 0; 36716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 368762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Tok.getLoc(); 36916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 370b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 37116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 372762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Parser.getTok().getLoc(); 373a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 37499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback = false; 3759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ParseWriteBack) { 37618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 3779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 378762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 3799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback = true; 380b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 3819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 38299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 38399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 3843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return ARMOperand::CreateReg(RegNum, Writeback, S, E); 385a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 386a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 387c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 388c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 389c0ddfaa134fe60c09686906b3a8f489531653453Chris LattnerARMOperand *ARMAsmParser::ParseRegisterList() { 390762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 39118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 392cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby "Token is not an Left Curly Brace"); 393762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 394b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 395d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 39618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 397d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 398c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 399c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 400c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 401c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 402d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 403c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 404c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 405c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 406c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 40716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 408b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 409d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby unsigned RegList = 1 << RegNum; 410d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 411d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int HighRegNum = RegNum; 412d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby // TODO ranges like "{Rn-Rm}" 41318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan while (Parser.getTok().is(AsmToken::Comma)) { 414b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 415d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 41618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 417d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 418c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 419c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 420c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 421c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 422d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 423c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 424c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 425c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 426c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 427d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 428d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegList & (1 << RegNum)) 429d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register duplicated in register list"); 430d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (RegNum <= HighRegNum) 431d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register not in ascending order in register list"); 432d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby RegList |= 1 << RegNum; 433d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby HighRegNum = RegNum; 434d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 435b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 436d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby } 43718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 438c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 439c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 440c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 441c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 442762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RCurlyTok.getLoc(); 443b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 444d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 445c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner // FIXME: Need to return an operand! 446c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(E, "FIXME: register list parsing not implemented"); 447c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 448d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 449d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 4509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true 4519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 4529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 4539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 454550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseMemory() { 455762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 45618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 4576bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby "Token is not an Left Bracket"); 458762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 459b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 46118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 462550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 463550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 464550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 465550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 466550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner int BaseRegNum = 0; 46761a4d56a03c051834ee25d8248fa9f434e7e8c19Benjamin Kramer if (ARMOperand *Op = MaybeParseRegister(false)) { 468550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner BaseRegNum = Op->getReg(); 46961a4d56a03c051834ee25d8248fa9f434e7e8c19Benjamin Kramer delete Op; 47061a4d56a03c051834ee25d8248fa9f434e7e8c19Benjamin Kramer } else { 471550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 472550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 473550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 477a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 478a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 4829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 48318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 485a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 486b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 4889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 492550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 493550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 494550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 49518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 496550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 497550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 498550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 499550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 500762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 501b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 502a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 50318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 504a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 505762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 506a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 507b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 508a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 510550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetRegShifted, ShiftType, ShiftAmount, 511550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Preindexed, Postindexed, Negative, Writeback, 512550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner S, E); 513a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // The "[Rn" we have so far was not followed by a comma. 515a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 5169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // This is a post indexing addressing forms, that is a ']' follows after 5179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // the "[Rn". 518a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Postindexed = true; 519a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 520762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 521b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 522a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 523e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 524a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 525a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 526a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 52714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner const MCExpr *Offset = 0; 528a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 52918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 530e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 531550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 532550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 533550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 534550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 535b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 536550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 53716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 538550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 539550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 540a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 541e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 542550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 543550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetRegShifted, ShiftType, ShiftAmount, 544550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Preindexed, Postindexed, Negative, Writeback, 545550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner S, E); 546a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 547a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 548550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 550a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 5529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 5539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 5549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 5559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 5569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 5579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 5589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 559762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 5609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 5619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 5629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 5639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 564762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 565762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 5669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 5679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 5689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 5699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 57018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 571762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 5729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 573b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 5749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 5759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 576b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 5779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 57918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 5809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 581550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = MaybeParseRegister(false)) { 582550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 583762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Op->getEndLoc(); 584762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegNum = Op->getReg(); 585550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner delete Op; 586762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 5879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 5899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 5909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 59118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 593b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 59518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 596762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 5973472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 5989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 5999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 6029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 60318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 60616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 607b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 6109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 611762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 6149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 6159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 619a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 62016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbachbool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, 621762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 62218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 624a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 62538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 626a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 6279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 628a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 6299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 630a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 6319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 632a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 6339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 634a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 6359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 636a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 637a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 638b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 639a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 6419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 6429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 643a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 64518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 648b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 6519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 655a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 6579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 658550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseOperand() { 659762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 66016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 661a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 662a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 663550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = MaybeParseRegister(true)) 664550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return Op; 66516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 666515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 667515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 668515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 669762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 670515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 671550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 672762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 673550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(IdVal, S, E); 674a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 675550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseMemory(); 676d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 677550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseRegisterList(); 678d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 679079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 680079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 681762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 682b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 684515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 685550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 686762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 687550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(ImmVal, S, E); 688a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 689550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(Parser.getTok().getLoc(), "unexpected token in operand"); 690550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 692a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 693a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 69538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 6969898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 6975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 6985747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 6995747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar StringRef Head = Name.slice(Start, Next); 7005747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 701345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Determine the predicate, if any. 702345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // 703345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: We need a way to check whether a prefix supports predication, 704345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // otherwise we will end up with an ambiguity for instructions that happen to 705345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // end with a predicate name. 706345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2)) 707345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("eq", ARMCC::EQ) 708345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ne", ARMCC::NE) 709345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hs", ARMCC::HS) 710345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lo", ARMCC::LO) 711345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("mi", ARMCC::MI) 712345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("pl", ARMCC::PL) 713345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vs", ARMCC::VS) 714345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vc", ARMCC::VC) 715345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hi", ARMCC::HI) 716345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ls", ARMCC::LS) 717345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ge", ARMCC::GE) 718345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lt", ARMCC::LT) 719345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("gt", ARMCC::GT) 720345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("le", ARMCC::LE) 721345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("al", ARMCC::AL) 722345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Default(~0U); 72316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 7243a69756e392942bc522193f38d7f33958ed3b131Chris Lattner if (CC != ~0U) 725345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Head = Head.slice(0, Head.size() - 2); 7263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner else 727345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar CC = ARMCC::AL; 728345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 7293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 7303a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), NameLoc)); 731345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 732345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 7335747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 7345747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 7355747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 7365747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Head = Name.slice(Start, Next); 737a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7383a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 7395747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 7405747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 7415747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 7425747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 743a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 744550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 745550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 746550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 747cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 748cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 749cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 750a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 751a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 752b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 753a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 754a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 755550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 756550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 757550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 758cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 759cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 760cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 761a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 762a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 76316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 764cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 765cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 76634e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 767cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 76834e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 7699898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 770ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 771ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 772fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 773fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 774fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 775fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 776fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 777fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 778e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { 779e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 780fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 781fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 78216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 783e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 784e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 785e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 786e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 787e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 788e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 789e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 790e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 79116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 792e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 793e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 794e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 79516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 796e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 797e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 798e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 799e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 800fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 80116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 802c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 803fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 804fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 805fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 806fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 807515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 808ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 809ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 810ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 811ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 813515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 814515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 815515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 816515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 817515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 819515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 820ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 821ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 822ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 823ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 824ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 825ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 826ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 827ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 828ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 829ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 830ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 831ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 832aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 833ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 834ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 835ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 83616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 837ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 838ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 839ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 840b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 841ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 842ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 843ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 844b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 845ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 846ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 847ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 848515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 849515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 850515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 851515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 852515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 853b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 854515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 855515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 856515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 858515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 859515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 860515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 861515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 862515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 863515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 86418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 865515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 866515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 867b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 868515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 869515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 870515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 871b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 872515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 873515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: mark symbol as a thumb symbol 874515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 875515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 876515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 877515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 878515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 879515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 880515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 88118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 882515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 883515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 88438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 88558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 886b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 88758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 888b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 889515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 890515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 891515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 892515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 89318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 894b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 895515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 896515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 897515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 898515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 899515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 900515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 901515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 902515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 903515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 90418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 905515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 906515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 90718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 90858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 909b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 91058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 911b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 912515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 913515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 914515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 915515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 91618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 917b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 918515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 919515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 920515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 921515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 922515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 923515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 92490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 92590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 9269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 927ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 928ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 929ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 93090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 931ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 9323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9330692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 9340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 9353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 936