ARMAsmParser.cpp revision 345a9a6269318c96f333c0492b23733e29d952df
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h" 113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h" 12c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 15ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 16ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 17ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h" 20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/Compiler.h" 21c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 22fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 23762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan#include "llvm/ADT/OwningPtr.h" 24c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 25345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 27ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 28ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 29ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbynamespace { 30ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbystruct ARMOperand; 31ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 32a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby// The shift types for register controlled shifts in arm memory addressing 33a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbyenum ShiftType { 34a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsl, 35a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsr, 36a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Asr, 37a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Ror, 38a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Rrx 39a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 40a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 41ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser { 42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 43d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar TargetMachine &TM; 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyprivate: 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 53ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 54762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool MaybeParseRegister(OwningPtr<ARMOperand> &Op, bool ParseWriteBack); 55a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 56762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseRegisterList(OwningPtr<ARMOperand> &Op); 57d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 58762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseMemory(OwningPtr<ARMOperand> &Op); 59a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 66762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 67762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 69762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); 70a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 71762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseOperand(OwningPtr<ARMOperand> &Op); 72a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 73ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 74ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 79515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 80515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 82515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 83a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 84a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar unsigned ComputeAvailableFeatures(const ARMSubtarget *Subtarget) const; 873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 889898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, 89a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby MCInst &Inst); 90a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 92a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 94ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 95d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) 96d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar : TargetAsmParser(T), Parser(_Parser), TM(_TM) {} 97ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 9838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 999898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 100ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 101ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 102ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 103ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 1067659389d0d4d315d30877592221da6a6f663114aChris Lattnerstruct ARMOperand : public MCParsedAsmOperand { 107762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananprivate: 108762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand() {} 109762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananpublic: 110762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 112cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 1138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 1148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 117a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 118762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 121a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 13299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback; 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 135cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby struct { 136cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 137cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 138762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // This is for all forms of ARM address expressions 140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 141a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned OffsetRegNum; // used when OffsetIsReg is true 1439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *Offset; // used when OffsetIsReg is false 144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 1459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType ShiftType; // used when OffsetRegShifted is true 1469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby unsigned 1479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted : 1, // only used when OffsetIsReg is true 1489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Preindexed : 1, 1499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Postindexed : 1, 1509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg : 1, 1519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative : 1, // only used when OffsetIsReg is true 1529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback : 1; 153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 155a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 156762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 157762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(KindTy K, SMLoc S, SMLoc E) 158762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan : Kind(K), StartLoc(S), EndLoc(E) {} 159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 163762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 164762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 1658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 1668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 1678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 168762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 1698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 173762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 177762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 178762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 179762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 183762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 184762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 185762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 186762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 1898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 1908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 1918462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 1928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Register && "Invalid access!"); 200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Reg.RegNum; 201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 203cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 204cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 205cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 206cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 207cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 2088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 2098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool isReg() const { return Kind == Register; } 213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isToken() const {return Kind == Token; } 2153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 2173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar // Add as immediates when possible. 2183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 2203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 2213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 2223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 225345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 2268462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 227345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: What belongs here? 228345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(0)); 2298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 2308462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 232a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 233a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 235a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 2373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 2383483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 2393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 241fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar virtual void dump(raw_ostream &OS) const; 242b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 243345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar static void CreateCondCode(OwningPtr<ARMOperand> &Op, ARMCC::CondCodes CC, 244345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar SMLoc S) { 245345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op.reset(new ARMOperand); 246345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->Kind = CondCode; 247345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 248345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 249345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 250345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 251345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 252762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateToken(OwningPtr<ARMOperand> &Op, StringRef Str, 253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S) { 254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Token; 256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 259762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 261a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateReg(OwningPtr<ARMOperand> &Op, unsigned RegNum, 263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool Writeback, SMLoc S, SMLoc E) { 264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Register; 266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.Writeback = Writeback; 268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 271a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateImm(OwningPtr<ARMOperand> &Op, const MCExpr *Val, 274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, SMLoc E) { 275762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 276762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Immediate; 277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 281cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 282cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 283762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan static void CreateMem(OwningPtr<ARMOperand> &Op, 284762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan unsigned BaseRegNum, bool OffsetIsReg, 285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *Offset, unsigned OffsetRegNum, 286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool OffsetRegShifted, enum ShiftType ShiftType, 287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *ShiftAmount, bool Preindexed, 288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool Postindexed, bool Negative, bool Writeback, 289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, SMLoc E) { 290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op.reset(new ARMOperand); 291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Kind = Memory; 292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 293762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Offset = Offset; 295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegNum = OffsetRegNum; 296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 297762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 311fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const { 312fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 313fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 314fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << ARMCondCodeToString(getCondCode()); 315fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 316fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 317fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 318fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 319fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 320fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "<memory>"; 321fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 322fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 323fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "<register " << getReg() << ">"; 324fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 325fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 326fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 327fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 328fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 329fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 3303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3313483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 3323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 3333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 3353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 3373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 3399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and if it is a register name a Reg operand is created, the token is eaten 3409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and false is returned. Else true is returned and no token is eaten. 3419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO this is likely to change to allow different register types and or to 3429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// parse for a specific register type. 343762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::MaybeParseRegister 344762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan (OwningPtr<ARMOperand> &Op, bool ParseWriteBack) { 345762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 34618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 347a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 348a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 350a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 351d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum; 352a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 353a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby RegNum = MatchRegisterName(Tok.getString()); 354d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 355a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 357762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Tok.getLoc(); 358762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 359b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 361762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Parser.getTok().getLoc(); 362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 36399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback = false; 3649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ParseWriteBack) { 36518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 3669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 3689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback = true; 369b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 3709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 37199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 37299e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 373762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateReg(Op, RegNum, Writeback, S, E); 37499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 375a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 376a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a register list, return false if successful else return true or an 3799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// error. The first token must be a '{' when called. 380762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) { 381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 38218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 383cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby "Token is not an Left Curly Brace"); 384762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 385b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 386d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 38718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 388d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 389d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 390d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 391d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 392d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 393d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 394b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 395d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby unsigned RegList = 1 << RegNum; 396d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 397d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int HighRegNum = RegNum; 398d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby // TODO ranges like "{Rn-Rm}" 39918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan while (Parser.getTok().is(AsmToken::Comma)) { 400b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 401d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 40218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 403d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 404d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 405d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 406d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 407d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 408d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 409d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 410d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegList & (1 << RegNum)) 411d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register duplicated in register list"); 412d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (RegNum <= HighRegNum) 413d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register not in ascending order in register list"); 414d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby RegList |= 1 << RegNum; 415d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby HighRegNum = RegNum; 416d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 417b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 418d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby } 41918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 420d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RCurlyTok.isNot(AsmToken::RCurly)) 421d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RCurlyTok.getLoc(), "'}' expected"); 422762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RCurlyTok.getLoc(); 423b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 424d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 425d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return false; 426d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 427d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 4289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true 4299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 4309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 4319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand> &Op) { 433762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 43418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 4356bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby "Token is not an Left Bracket"); 436762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 437b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 438a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 43918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 440a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (BaseRegTok.isNot(AsmToken::Identifier)) 441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 4429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (MaybeParseRegister(Op, false)) 443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 444762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int BaseRegNum = Op->getReg(); 445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 446a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 447a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 448a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 4539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 45418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 456a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 457b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 4599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 461a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 462a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 4639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 464762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Offset, OffsetIsReg, OffsetRegNum, E)) 4659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 46618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 467a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (RBracTok.isNot(AsmToken::RBrac)) 468a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(RBracTok.getLoc(), "']' expected"); 469762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 470b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 471a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 47218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 476b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 477a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 479762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegShifted, ShiftType, ShiftAmount, 480762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Preindexed, Postindexed, Negative, Writeback, S, E); 481a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 482a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // The "[Rn" we have so far was not followed by a comma. 484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 4859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // This is a post indexing addressing forms, that is a ']' follows after 4869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // the "[Rn". 487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Postindexed = true; 488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 489762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 490b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 492e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 494a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 49818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 499e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 500e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::Comma)) 5013472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(NextTok.getLoc(), "',' expected"); 502b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 504762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 505762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E)) 5069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 508e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 509762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 510762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegShifted, ShiftType, ShiftAmount, 511762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Preindexed, Postindexed, Negative, Writeback, S, E); 512a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 513a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 515a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 516a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 517a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 5199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 5209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 5219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 5229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 5239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 5249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 5259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 526762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 5279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 5289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 5299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 5309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 531762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 532762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 533762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 5349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 5359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 5369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 5379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 53818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 539762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 5409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 541b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 5429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 5439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 544b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 5459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 54718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 5489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 5499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = !MaybeParseRegister(Op, false); 550762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (OffsetIsReg) { 551762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Op->getEndLoc(); 552762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OffsetRegNum = Op->getReg(); 553762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 5549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 5569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 5579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 55818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 5599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 560b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 56218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 563762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 5643472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 5659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 5669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 5699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 57018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 5719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 5729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 573762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 574b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 5759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 5769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 5779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 578762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 5799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 5809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 5819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 5829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 583a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 584a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 585a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 586a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 587762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseShift(ShiftType &St, 588762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan const MCExpr *&ShiftAmount, 589762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 59018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 591a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 592a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 59338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 594a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 5959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 596a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 5979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 598a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 5999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 600a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 6019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 602a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 6039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 604a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 605a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 606b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 6099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 6109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 611a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 61318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 616b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 6199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 620a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 621a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 6259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 626762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananbool ARMAsmParser::ParseOperand(OwningPtr<ARMOperand> &Op) { 627762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 628762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan 629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 630a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 6319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (!MaybeParseRegister(Op, true)) 632a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 633515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 634515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 635515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 636762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 637515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 638515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return true; 639762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 640762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateImm(Op, IdVal, S, E); 641515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 642a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 643515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseMemory(Op); 644d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 645515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseRegisterList(Op); 646d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 647079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 648079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 649762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 650b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 651515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 652515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 653cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return true; 654762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 655762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand::CreateImm(Op, ImmVal, S, E); 656cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return false; 657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 65818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in operand"); 659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 661a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 66338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 6649898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 665762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 6665747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 6675747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 6685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 6695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar StringRef Head = Name.slice(Start, Next); 6705747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 671345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Determine the predicate, if any. 672345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // 673345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: We need a way to check whether a prefix supports predication, 674345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // otherwise we will end up with an ambiguity for instructions that happen to 675345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // end with a predicate name. 676345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2)) 677345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("eq", ARMCC::EQ) 678345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ne", ARMCC::NE) 679345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hs", ARMCC::HS) 680345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lo", ARMCC::LO) 681345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("mi", ARMCC::MI) 682345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("pl", ARMCC::PL) 683345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vs", ARMCC::VS) 684345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vc", ARMCC::VC) 685345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hi", ARMCC::HI) 686345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ls", ARMCC::LS) 687345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ge", ARMCC::GE) 688345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lt", ARMCC::LT) 689345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("gt", ARMCC::GT) 690345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("le", ARMCC::LE) 691345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("al", ARMCC::AL) 692345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Default(~0U); 693345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar if (CC != ~0U) { 694345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Head = Head.slice(0, Head.size() - 2); 695345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } else 696345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar CC = ARMCC::AL; 697345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 6985747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar ARMOperand::CreateToken(Op, Head, NameLoc); 699762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 700a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 701345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar ARMOperand::CreateCondCode(Op, ARMCC::CondCodes(CC), NameLoc); 702345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Operands.push_back(Op.take()); 703345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 704345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 7055747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 7065747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 7075747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 7085747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Head = Name.slice(Start, Next); 709a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7105747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar ARMOperand::CreateToken(Op, Head, NameLoc); 7115747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Operands.push_back(Op.take()); 7125747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 7135747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 7145747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 7155747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 716a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 717762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan OwningPtr<ARMOperand> Op; 7189898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 719762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 720a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 721a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 722b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 723a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 724a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 7259898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 726762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Operands.push_back(Op.take()); 727a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 728a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 7299898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 730ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 731ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 732515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 733ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 734ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 735ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 736ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 737515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 738515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 739515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 740515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 742515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 744515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 745ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 746ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 747ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 748ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 749ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 750ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 751ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 752ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 753ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 754ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 755ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 756ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 757aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 758ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 759ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 760ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 761ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 762ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 763ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 764ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 765b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 766ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 767ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 768ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 769b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 770ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 771ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 772ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 773515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 774515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 775515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 776515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 777515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 778b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 779515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 780515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 781515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 782515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 783515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 784515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 785515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 786515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 787515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 788515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 78918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 790515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 791515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 79218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier(); 793b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 796515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 797b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 798515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 799515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: mark symbol as a thumb symbol 800515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 801515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 802515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 803515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 804515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 805515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 806515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 80718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 808515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 809515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 81038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 81158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 812b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 81358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 814b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 815515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 816515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 817515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 81918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 820b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 821515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 822515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 823515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 824515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 825515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 826515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 827515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 828515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 829515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 83018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 831515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 832515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 83318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 83458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 835b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 83658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 837b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 838515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 839515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 840515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 841515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 84218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 843b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 844515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 845515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 846515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 847515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 848515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 849515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 85090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 85190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 8529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 853ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 854ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 855ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 85690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 857ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 8583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 8593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 860