ARMAsmParser.cpp revision c223e2b10b4753a63dfe7e6980c650b179139983
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; 383a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 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); 82fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 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}; 1013a69756e392942bc522193f38d7f33958ed3b131Chris Lattner} // end anonymous namespace 102ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 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; 137762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 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 }; 155762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 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 } 178762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 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 } 23614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner 23714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner 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; 24314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner 24414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner return true; 24514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 24614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner 24714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 24814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 24914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner 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; 310762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 3133a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3153a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 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; 367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 368762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Tok.getLoc(); 369762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 370b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 371762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 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 } 407c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner 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; 467550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = MaybeParseRegister(false)) 468550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner BaseRegNum = Op->getReg(); 469550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 470550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 471550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 472550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 477a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 478a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 4819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 48218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 485b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 4879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 491550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 492550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 493550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 49418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 495550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 496550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 497550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 498550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 500b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 50218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 503a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 504762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 506b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 508550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetRegShifted, ShiftType, ShiftAmount, 510550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Preindexed, Postindexed, Negative, Writeback, 511550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner S, E); 512a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 513a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // The "[Rn" we have so far was not followed by a comma. 514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 5159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // This is a post indexing addressing forms, that is a ']' follows after 5169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // the "[Rn". 517a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Postindexed = true; 518a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 519762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 520b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 522e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 523a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 524a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 525a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 52614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner const MCExpr *Offset = 0; 527a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 52818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 529e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 530550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 531550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 532550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 533550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 534b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 535550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 536550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 537550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 538550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 539a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 540e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 541550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 542550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetRegShifted, ShiftType, ShiftAmount, 543550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Preindexed, Postindexed, Negative, Writeback, 544550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner S, E); 545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 546a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 547550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 548a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 5519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 5529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 5539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 5549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 5559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 5569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 5579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 558762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 5599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 5609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 5619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 5629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 563762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 564762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 5659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 5669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 5679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 5689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 56918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 570762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 5719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 572b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 5739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 5749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 575b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 5769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 57818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 5799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 580550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = MaybeParseRegister(false)) { 581550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 582762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Op->getEndLoc(); 583762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegNum = Op->getReg(); 584550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner delete Op; 585762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 5869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 5889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 5899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 59018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 592b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 59418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 595762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 5963472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 5979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 5989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 6019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 60218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 605762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 606b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 6099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 610762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 6139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 6149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 615a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 6193a69756e392942bc522193f38d7f33958ed3b131Chris Lattnerbool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, 620762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 62118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 62438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 6269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 627a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 6289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 6309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 631a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 6329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 633a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 6349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 635a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 636a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 637b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 638a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 6409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 6419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 642a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 64418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 647b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 6509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 651a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 6569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 657550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseOperand() { 658762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 659762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 661a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 662550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = MaybeParseRegister(true)) 663550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return Op; 664550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner 665515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 666515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 667515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 668762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 669515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 670550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 671762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 672550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(IdVal, S, E); 673a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 674550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseMemory(); 675d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 676550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseRegisterList(); 677d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 678079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 679079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 680762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 681b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 682515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 684550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 685762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 686550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(ImmVal, S, E); 687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 688550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(Parser.getTok().getLoc(), "unexpected token in operand"); 689550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 690a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 692a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 69438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 6959898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 6965747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 6975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 6985747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar StringRef Head = Name.slice(Start, Next); 6995747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 700345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Determine the predicate, if any. 701345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // 702345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: We need a way to check whether a prefix supports predication, 703345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // otherwise we will end up with an ambiguity for instructions that happen to 704345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // end with a predicate name. 705345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2)) 706345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("eq", ARMCC::EQ) 707345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ne", ARMCC::NE) 708345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hs", ARMCC::HS) 709345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lo", ARMCC::LO) 710345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("mi", ARMCC::MI) 711345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("pl", ARMCC::PL) 712345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vs", ARMCC::VS) 713345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vc", ARMCC::VC) 714345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hi", ARMCC::HI) 715345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ls", ARMCC::LS) 716345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ge", ARMCC::GE) 717345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lt", ARMCC::LT) 718345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("gt", ARMCC::GT) 719345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("le", ARMCC::LE) 720345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("al", ARMCC::AL) 721345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Default(~0U); 7223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 7233a69756e392942bc522193f38d7f33958ed3b131Chris Lattner if (CC != ~0U) 724345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Head = Head.slice(0, Head.size() - 2); 7253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner else 726345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar CC = ARMCC::AL; 727345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 7283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 7293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), NameLoc)); 730345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 731345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 7325747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 7335747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 7345747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 7355747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Head = Name.slice(Start, Next); 736a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 7385747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 7395747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 7405747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 7415747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 742a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 743550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 744550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 745550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 746cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 747cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 748cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 749a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 750a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 751b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 752a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 753a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 754550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 755550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 756550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 757cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 758cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 759cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 760a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 761a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 76234e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner 763cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 764cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 76534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 766cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 76734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 7689898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 769ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 770ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 771fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 772fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 773fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 774fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 775fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 776fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 777e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { 778e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 779fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 780fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 781e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner 782e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 783e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 784e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 785e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 786e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 787e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 788e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 789e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 790e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner 791e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 792e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 793e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 794e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner 795e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 796e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 797e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 798e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 799fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 800c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher 801c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 802fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 803fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 804fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 805fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 806515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 807ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 808ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 809ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 810ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 813515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 814515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 815515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 816515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 817515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 819ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 820ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 821ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 822ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 823ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 824ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 825ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 826ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 827ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 828ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 829ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 830ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 831aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 832ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 833ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 834ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 835ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 836ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 837ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 838ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 839b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 840ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 841ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 842ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 843b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 844ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 845ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 846ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 847515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 848515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 849515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 850515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 851515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 852b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 853515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 854515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 855515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 856515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 858515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 859515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 860515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 861515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 862515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 86318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 864515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 865515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 866b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 867515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 868515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 869515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 870b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 871515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 872515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: mark symbol as a thumb symbol 873515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 874515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 875515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 876515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 877515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 878515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 879515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 88018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 881515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 882515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 88338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 88458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 885b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 88658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 887b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 888515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 889515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 890515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 891515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 89218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 893b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 894515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 895515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 896515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 897515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 898515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 899515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 900515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 901515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 902515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 90318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 904515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 905515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 90618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 90758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 908b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 90958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 910b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 911515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 912515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 913515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 914515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 91518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 916b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 917515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 918515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 919515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 920515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 921515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 922515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 92390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 92490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 9259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 926ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 927ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 928ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 92990b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 930ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 9313483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9320692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 9330692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 9343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 935