ARMAsmParser.cpp revision 642fc9c24ba7c43a4a962c6c05cfffce713d7de7
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" 1192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling#include "ARMAddressingModes.h" 123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 16642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 17ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h" 22c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 23fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.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 29a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby// The shift types for register controlled shifts in arm memory addressing 30a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbyenum ShiftType { 31a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsl, 32a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsr, 33a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Asr, 34a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Ror, 35a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Rrx 36a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 37a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 393a69756e392942bc522193f38d7f33958ed3b131Chris Lattner struct ARMOperand; 4016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 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 54e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int TryParseRegister(); 55e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner ARMOperand *TryParseRegisterWithWriteBack(); 56c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner ARMOperand *ParseRegisterList(); 57550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner ARMOperand *ParseMemory(); 58a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 65762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 66762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E); 679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 68762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); 69a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 70550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner ARMOperand *ParseOperand(); 71a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 72ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 73ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 79515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 80515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 827036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner bool MatchAndEmitInstruction(SMLoc IDLoc, 837c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 84fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out); 8516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 86a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 87a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 890692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 900692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 92a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 94a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 95ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 96d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM) 97833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach : TargetAsmParser(T), Parser(_Parser), TM(_TM) { 98833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach // Initialize the set of available features. 99833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach setAvailableFeatures(ComputeAvailableFeatures( 100833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach &TM.getSubtarget<ARMSubtarget>())); 101833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach } 102ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 10338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc, 1049898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 105ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 106ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 107ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 10816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 10916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1103a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1113a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 112a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 113a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 1147659389d0d4d315d30877592221da6a6f663114aChris Lattnerstruct ARMOperand : public MCParsedAsmOperand { 115762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callananpublic: 116762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1178462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 118cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 1198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 1208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 1218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 122a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 123a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 124762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 125a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 1288462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 1298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 1308462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 1318462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 13899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback; 139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 141cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby struct { 142cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 143cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 14416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // This is for all forms of ARM address expressions 146a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 147a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 148a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned OffsetRegNum; // used when OffsetIsReg is true 1499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *Offset; // used when OffsetIsReg is false 150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 1519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType ShiftType; // used when OffsetRegShifted is true 1529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby unsigned 1539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted : 1, // only used when OffsetIsReg is true 1549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Preindexed : 1, 1559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Postindexed : 1, 1569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg : 1, 1579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative : 1, // only used when OffsetIsReg is true 1589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback : 1; 159a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 160a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 161a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 16216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 163762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 164762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 165762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 166762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 167762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 1688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 1698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 1708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 1728462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 173762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 176762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 177762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 178762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 179762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 183762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 184762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 18516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 186762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 187762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 188762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 189762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 190a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1918462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 1928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 1938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 1948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 1958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Register && "Invalid access!"); 203a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Reg.RegNum; 204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 205a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 206cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 207cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 208cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 209cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 210cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 2118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 2123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool isReg() const { return Kind == Register; } 21414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 21514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 2163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 21814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 21914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 22014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 22114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 2223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 2233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 2243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 2253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 2263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 2278462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 228345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 2298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 230345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: What belongs here? 231345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(0)); 2328462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 2338462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 235a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 236a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 237a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 238a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 2403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 2413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 2423483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 24316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 24416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 24514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemMode5() const { 24614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted || 24780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Mem.Writeback || Mem.Negative) 24814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner return false; 24980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there is an offset expression, make sure it's valid. 25080eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach if (!Mem.Offset) 25180eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach return true; 25280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset); 25380eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach if (!CE) 25480eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach return false; 25580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // The offset must be a multiple of 4 in the range 0-1020. 25680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach int64_t Value = CE->getValue(); 25780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020); 25814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 25916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 26014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner void addMemMode5Operands(MCInst &Inst, unsigned N) const { 26114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(N == 2 && isMemMode5() && "Invalid number of operands!"); 26216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 26314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 26414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner assert(!Mem.OffsetIsReg && "invalid mode 5 operand"); 26592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 26680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // FIXME: #-0 is encoded differently than #0. Does the parser preserve 26780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // the difference? 26880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach if (Mem.Offset) { 26980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset); 27092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling assert(CE && "Non-constant mode 5 offset operand!"); 27192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 27280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // The MCInst offset operand doesn't include the low two bits (like 27380eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // the instruction encoding). 27492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling int64_t Offset = CE->getValue() / 4; 27592b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling if (Offset >= 0) 27692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, 27792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Offset))); 27892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling else 27992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, 28092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling -Offset))); 28192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling } else { 28280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 28392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling } 28414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 2853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 286fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar virtual void dump(raw_ostream &OS) const; 287b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 2883a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 2893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 290345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 291345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 292345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 2933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 294345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 295345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 2973a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 3023a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3053a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateReg(unsigned RegNum, bool Writeback, SMLoc S, 3063a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc E) { 3073a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.Writeback = Writeback; 310762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 3123a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3153a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 3163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 317762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 318762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 319762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 3203a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 321cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 322cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 3233a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg, 3243a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *Offset, unsigned OffsetRegNum, 3253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool OffsetRegShifted, enum ShiftType ShiftType, 3263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner const MCExpr *ShiftAmount, bool Preindexed, 3273a69756e392942bc522193f38d7f33958ed3b131Chris Lattner bool Postindexed, bool Negative, bool Writeback, 3283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 3293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 330762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 331762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetIsReg = OffsetIsReg; 332762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Offset = Offset; 333762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegNum = OffsetRegNum; 334762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.OffsetRegShifted = OffsetRegShifted; 335762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 336762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftAmount = ShiftAmount; 337762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Preindexed = Preindexed; 338762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Postindexed = Postindexed; 339762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Negative = Negative; 340762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.Writeback = Writeback; 34116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 342762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 343762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 3443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 345a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 34616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3473a69756e392942bc522193f38d7f33958ed3b131Chris Lattnerprivate: 3483a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand(KindTy K) : Kind(K) {} 349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 350a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 351a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 352a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 353fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const { 354fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 355fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 356fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << ARMCondCodeToString(getCondCode()); 357fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 358fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 359fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 360fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 361fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 362fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "<memory>"; 363fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 364fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 365fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "<register " << getReg() << ">"; 366fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 367fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 368fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 369fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 370fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 371fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 3723483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3733483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 3743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 3753483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3763483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 3773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 3793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 3809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 381e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 382e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 3833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 384e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() { 38518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 386a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 387d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 388a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 389a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 390e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int RegNum = MatchRegisterName(Tok.getString()); 391d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 392e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return -1; 393b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 394e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 395e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 396d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 397d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 398e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// Try to parse a register name. The token must be an Identifier when called, 399e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 400e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 401e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 402e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 403e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 404e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris LattnerARMOperand *ARMAsmParser::TryParseRegisterWithWriteBack() { 405e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 406e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int RegNo = TryParseRegister(); 407e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (RegNo == -1) return 0; 408d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 409e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc E = Parser.getTok().getLoc(); 410a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 41199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback = false; 412e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 413e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 414e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = ExclaimTok.getLoc(); 415e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Writeback = true; 416e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 41799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 41899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 419e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return ARMOperand::CreateReg(RegNo, Writeback, S, E); 420a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 421a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 422c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 423c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 424c0ddfaa134fe60c09686906b3a8f489531653453Chris LattnerARMOperand *ARMAsmParser::ParseRegisterList() { 425762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 42618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 427cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby "Token is not an Left Curly Brace"); 428762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 429b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 430d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 43118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 432d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 433c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 434c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 435c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 436c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 437d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 438c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 439c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 440c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 441c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 44216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 443b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 444d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby unsigned RegList = 1 << RegNum; 445d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 446d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int HighRegNum = RegNum; 447d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby // TODO ranges like "{Rn-Rm}" 44818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan while (Parser.getTok().is(AsmToken::Comma)) { 449b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 450d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 45118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 452d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 453c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 454c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 455c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 456c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 457d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 458c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 459c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 460c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 461c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 462d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 463d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegList & (1 << RegNum)) 464d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register duplicated in register list"); 465d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (RegNum <= HighRegNum) 466d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register not in ascending order in register list"); 467d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby RegList |= 1 << RegNum; 468d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby HighRegNum = RegNum; 469d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 470b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 471d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby } 47218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 473c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 474c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 475c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 476c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RCurlyTok.getLoc(); 478b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 479d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 480c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner // FIXME: Need to return an operand! 481c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(E, "FIXME: register list parsing not implemented"); 482c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 483d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 484d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 4859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true 4869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 4879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 4889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 489550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseMemory() { 490762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 49118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 4926bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby "Token is not an Left Bracket"); 493762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 494b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 49618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 497550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 498550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 499550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 500550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 501e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int BaseRegNum = TryParseRegister(); 502e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (BaseRegNum == -1) { 503550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 504550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 505550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 506a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 508a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 509a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 510a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 511a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 512a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 5149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 51518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 516a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 517a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 518b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 5209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 522a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 523a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 524550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 525550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 526550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 52718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 528550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 529550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 530550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 531550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 532762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 533b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 534a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 53518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 536a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 537762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 538a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 539b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 540a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin 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 // The "[Rn" we have so far was not followed by a comma. 547a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 54880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there's anything other than the right brace, this is a post indexing 54980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // addressing form. 550762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 551b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 552a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 553e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 555a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 556a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 55714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner const MCExpr *Offset = 0; 558a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 55918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 560e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 56180eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Postindexed = true; 56280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Writeback = true; 563550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 564550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 565550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 566550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 567b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 568550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 56916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 570550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 571550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 572a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 573e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 574550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 575550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetRegShifted, ShiftType, ShiftAmount, 576550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Preindexed, Postindexed, Negative, Writeback, 577550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner S, E); 578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 579a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 580550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 581a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 582a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 5849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 5859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 5869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 5879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 5889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 5899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 5909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 591762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 5929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 5939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 5949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 5959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 596762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 597762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 5989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 5999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 6009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 6019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 60218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 603762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 6049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 605b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 6069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 6079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 608b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 6099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 61118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 6129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 613e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc CurLoc = OffsetRegTok.getLoc(); 614e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner OffsetRegNum = TryParseRegister(); 615e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (OffsetRegNum != -1) { 616550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 617e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = CurLoc; 618762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 6199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 620d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 6219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 6229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 6239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 62418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 6259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 626b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 6279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 62818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 629762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 6303472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 6319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 6329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 6359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 63618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 63916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 640b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 6439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 644762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 6479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 6489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 649a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 650a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 651a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 65316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbachbool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, 654762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 65518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 656a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 65838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 6609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 661a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 6629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 663a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 6649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 665a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 6669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 667a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 6689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 669a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 670a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 671b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 672a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 6749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 6759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 676a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 67818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 681b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 6849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 685a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 686a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 688a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 6909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 691550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseOperand() { 692762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 69316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 694a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 695a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 696e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ARMOperand *Op = TryParseRegisterWithWriteBack()) 697550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return Op; 69816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 699515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 700515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 701515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 702762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 703515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 704550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 705762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 706550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(IdVal, S, E); 707a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 708550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseMemory(); 709d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 710550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseRegisterList(); 711d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 712079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 713079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 714762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 715b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 716515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 717515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 718550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 719762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 720550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(ImmVal, S, E); 721a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 722550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(Parser.getTok().getLoc(), "unexpected token in operand"); 723550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 724a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 725a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 726a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 72838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 7299898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 7305747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 7315747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 7325747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar StringRef Head = Name.slice(Start, Next); 7335747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 734345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Determine the predicate, if any. 735345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // 736345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: We need a way to check whether a prefix supports predication, 737345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // otherwise we will end up with an ambiguity for instructions that happen to 738345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // end with a predicate name. 7393df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // FIXME: Likewise, some arithmetic instructions have an 's' prefix which 7403df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // indicates to update the condition codes. Those instructions have an 7413df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // additional immediate operand which encodes the prefix as reg0 or CPSR. 7423df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // Just checking for a suffix of 's' definitely creates ambiguities; e.g, 7433df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // the SMMLS instruction. 744345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2)) 745345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("eq", ARMCC::EQ) 746345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ne", ARMCC::NE) 747345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hs", ARMCC::HS) 748345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lo", ARMCC::LO) 749345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("mi", ARMCC::MI) 750345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("pl", ARMCC::PL) 751345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vs", ARMCC::VS) 752345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vc", ARMCC::VC) 753345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hi", ARMCC::HI) 754345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ls", ARMCC::LS) 755345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ge", ARMCC::GE) 756345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lt", ARMCC::LT) 757345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("gt", ARMCC::GT) 758345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("le", ARMCC::LE) 759345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("al", ARMCC::AL) 760345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Default(~0U); 76116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 762dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner if (CC == ~0U || 763dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner (CC == ARMCC::LS && (Head == "vmls" || Head == "vnmls"))) { 764345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar CC = ARMCC::AL; 765dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner } else { 766dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner Head = Head.slice(0, Head.size() - 2); 76752925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 768345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 7693a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 770469ebbe148b18a78963e8bc3fa7ae8e5700d8d27Jim Grosbach // FIXME: Should only add this operand for predicated instructions 7713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), NameLoc)); 772345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 773345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 7745747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 7755747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 7765747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 7775747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Head = Name.slice(Start, Next); 778a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7793a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 7805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 7815747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 7825747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 7835747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 784a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 785550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 786550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 787550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 788cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 789cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 790cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 791a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 792a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 793b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 794a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 795a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 796550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 797550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 798550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 799cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 800cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 801cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 802a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 803a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 80416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 805cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 806cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 80734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 808cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 80934e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 8109898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 811ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 812ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 813fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 814fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 815fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 816fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 817fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 818fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 819e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { 820e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 821fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 822fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 82316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 824e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 825e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 826e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 827e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 828e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 829e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 830e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 831e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 83216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 833e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 834e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 835e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 83616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 837e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 838e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 839e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 840e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 841fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 84216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 843c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 844fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 845fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 846fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 847fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 848515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 849ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 850ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 851ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 852ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 853515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 854515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 855515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 856515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 858515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 859515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 860515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 861ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 862ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 863ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 864ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 865ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 866ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 867ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 868ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 869ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 870ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 871ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 872ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 873aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 874ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 875ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 876ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 87716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 878ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 879ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 880ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 881b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 882ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 883ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 884ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 885b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 886ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 887ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 888ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 889515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 890515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 891515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 892515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 893515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 894b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 895515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 896515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 897515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 898515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 899515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 900515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 901515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 902515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 903515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 904515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 90518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 906515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 90783c4018fcca18fe9c281c3943fc58a17621636c4Jim Grosbach return Error(L, "unexpected token in .thumb_func directive"); 908642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach StringRef Name = Tok.getString(); 909b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 910515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 911515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 912b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 913515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 914642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 915642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 916642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 917515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 918515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 919515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 920515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 921515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 922515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 92318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 924515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 925515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 92638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 92758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 928b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 92958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 930b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 931515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 932515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 933515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 934515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 93518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 936b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 937515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 938515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 939515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 940515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 941515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 942515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 943515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 944515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 945515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 94618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 947515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 948515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 94918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 95058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 951b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 95258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 953b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 954515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 955515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 956515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 957515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 95818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 959b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 960515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 961515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 962515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 963515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 964515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 965515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 96690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 96790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 9689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 969ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 970ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 971ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 97290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 973ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 9743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9750692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 9760692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 9773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 978