ARMAsmParser.cpp revision a60f157b7c6fb60b33598fa5143ed8cb91aa5107
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)); 264a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling 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. 390d68fd9c79eeb30980c18dc3f74b2da839bb259f3Bill Wendling unsigned RegNum = MatchRegisterName(Tok.getString()); 391d68fd9c79eeb30980c18dc3f74b2da839bb259f3Bill Wendling if (RegNum == 0) 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) && 427a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a 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 } 4371d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling int RegNum = TryParseRegister(); 438c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 439c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 440c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 441c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 44216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 443d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby unsigned RegList = 1 << RegNum; 444d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 445d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int HighRegNum = RegNum; 446d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby // TODO ranges like "{Rn-Rm}" 44718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan while (Parser.getTok().is(AsmToken::Comma)) { 448b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 449d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 45018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 451d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 452c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 453c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 454c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 455c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 4561d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling int RegNum = TryParseRegister(); 457c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 458c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 459c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 460c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 461d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 462d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegList & (1 << RegNum)) 463d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register duplicated in register list"); 464d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (RegNum <= HighRegNum) 465d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register not in ascending order in register list"); 466d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby RegList |= 1 << RegNum; 467d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby HighRegNum = RegNum; 468d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby } 46918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 470c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 471c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 472c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 473c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RCurlyTok.getLoc(); 475b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 476d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 477c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner // FIXME: Need to return an operand! 478c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(E, "FIXME: register list parsing not implemented"); 479c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner return 0; 480d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 481d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 4829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true 4839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 4849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 4859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 486550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseMemory() { 487762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 48818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 489a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 490762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 491b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 49318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 494550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (BaseRegTok.isNot(AsmToken::Identifier)) { 495550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 496550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 497550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 498e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner int BaseRegNum = TryParseRegister(); 499e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (BaseRegNum == -1) { 500550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(BaseRegTok.getLoc(), "register expected"); 501550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 502550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 503a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 504a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 506a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 508a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 509a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 5119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 51218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 513a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 515b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 5169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 5179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 518a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 519a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 520a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 521550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 522550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Offset, OffsetIsReg, OffsetRegNum, E)) 523550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 52418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 525550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (RBracTok.isNot(AsmToken::RBrac)) { 526550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(RBracTok.getLoc(), "']' expected"); 527550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 528550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 529762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = RBracTok.getLoc(); 530b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 531a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 53218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 533a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 534762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = ExclaimTok.getLoc(); 535a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 536b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 537a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 538550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 539550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetRegShifted, ShiftType, ShiftAmount, 540550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Preindexed, Postindexed, Negative, Writeback, 541550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner S, E); 542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // The "[Rn" we have so far was not followed by a comma. 544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 54580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // If there's anything other than the right brace, this is a post indexing 54680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach // addressing form. 547762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 548b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 550e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 551a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 552a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 553a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 55414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner const MCExpr *Offset = 0; 555a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 55618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 557e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 55880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Postindexed = true; 55980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach Writeback = true; 560550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (NextTok.isNot(AsmToken::Comma)) { 561550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(NextTok.getLoc(), "',' expected"); 562550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 563550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner } 564b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 565550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 56616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, 567550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner E)) 568550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 569a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 570e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 571550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 572550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetRegShifted, ShiftType, ShiftAmount, 573550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Preindexed, Postindexed, Negative, Writeback, 574550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner S, E); 575a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 576a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 577550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 579a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 5819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 5829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 5839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 5849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 5859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 5869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 5879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 588762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan bool &OffsetRegShifted, 5899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 5909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 5919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 5929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 593762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan int &OffsetRegNum, 594762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 5959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 5969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 5979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 5989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 59918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 600762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = NextTok.getLoc(); 6019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 602b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 6039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 6049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 605b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 6069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 60818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 6099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 610e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc CurLoc = OffsetRegTok.getLoc(); 611e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner OffsetRegNum = TryParseRegister(); 612e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (OffsetRegNum != -1) { 613550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner OffsetIsReg = true; 614e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner E = CurLoc; 615762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 6169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 617d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 6189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 6199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 6209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 62118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 6229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 623b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 6249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 62518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 626762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan if (ParseShift(ShiftType, ShiftAmount, E)) 6273472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands return Error(Tok.getLoc(), "shift expected"); 6289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 6299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 6329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 63318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 63616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 637b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 6409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 641762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 6439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 6449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 6459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 646a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 647a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 648a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 649a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 65016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbachbool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount, 651762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc &E) { 65218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 65538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 656a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 6579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 658a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 6599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 6619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 662a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 6639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 664a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 6659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 666a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 667a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 668b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 669a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 6719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 6729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 673a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 67518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 6769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 6779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 678b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 6799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 6809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 6819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 682a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 683a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 684a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 685a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 6869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 6879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 688550276ee5bb3e115d4d81156dceffb9d3d78823aChris LattnerARMOperand *ARMAsmParser::ParseOperand() { 689762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 69016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 692a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 693e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ARMOperand *Op = TryParseRegisterWithWriteBack()) 694550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return Op; 69516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 696515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 697515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 698515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 699762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 700515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 701550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 702762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 703550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(IdVal, S, E); 704a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 705550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseMemory(); 706d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 707550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ParseRegisterList(); 708d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 709079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 710079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 711762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 712b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 713515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 714515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 715550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 716762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 717550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return ARMOperand::CreateImm(ImmVal, S, E); 718a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 719550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Error(Parser.getTok().getLoc(), "unexpected token in operand"); 720550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner return 0; 721a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 722a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 723a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 72538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramerbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 7269898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 7275747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 7285747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 7295747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar StringRef Head = Name.slice(Start, Next); 7305747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 731345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Determine the predicate, if any. 732345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // 733345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // FIXME: We need a way to check whether a prefix supports predication, 734345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // otherwise we will end up with an ambiguity for instructions that happen to 735345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // end with a predicate name. 7363df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // FIXME: Likewise, some arithmetic instructions have an 's' prefix which 7373df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // indicates to update the condition codes. Those instructions have an 7383df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // additional immediate operand which encodes the prefix as reg0 or CPSR. 7393df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // Just checking for a suffix of 's' definitely creates ambiguities; e.g, 7403df518e67edaf358154af394cc99d21435b7b118Jim Grosbach // the SMMLS instruction. 741345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2)) 742345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("eq", ARMCC::EQ) 743345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ne", ARMCC::NE) 744345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hs", ARMCC::HS) 745345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lo", ARMCC::LO) 746345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("mi", ARMCC::MI) 747345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("pl", ARMCC::PL) 748345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vs", ARMCC::VS) 749345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("vc", ARMCC::VC) 750345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("hi", ARMCC::HI) 751345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ls", ARMCC::LS) 752345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("ge", ARMCC::GE) 753345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("lt", ARMCC::LT) 754345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("gt", ARMCC::GT) 755345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("le", ARMCC::LE) 756345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Case("al", ARMCC::AL) 757345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar .Default(~0U); 75816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 759dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner if (CC == ~0U || 760dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner (CC == ARMCC::LS && (Head == "vmls" || Head == "vnmls"))) { 761345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar CC = ARMCC::AL; 762dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner } else { 763dba34d874d0ac8c334f03d770b80c6ee2f12808aChris Lattner Head = Head.slice(0, Head.size() - 2); 76452925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 765345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 7663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 767469ebbe148b18a78963e8bc3fa7ae8e5700d8d27Jim Grosbach // FIXME: Should only add this operand for predicated instructions 7683a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), NameLoc)); 769345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 770345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 7715747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 7725747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 7735747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 7745747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Head = Name.slice(Start, Next); 775a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 7763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); 7775747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 7785747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 7795747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 7805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 781a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 782550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 783550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 784550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 785cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 786cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 787cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 788a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 789a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 790b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 791a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 792a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 793550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner if (ARMOperand *Op = ParseOperand()) 794550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner Operands.push_back(Op); 795550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner else { 796cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 797cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 798cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 799a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 800a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 80116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 802cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 803cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 80434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 805cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 80634e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 8079898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 808ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 809ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 810fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 811fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 812fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 813fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 814fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 815fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 816e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { 817e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 818fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 819fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 82016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 821e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 822e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 823e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 824e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 825e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 826e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 827e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 828e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 82916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 830e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 831e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 832e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 83316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 834e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 835e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 836e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 837e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "unrecognized instruction mnemonic"); 838fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 83916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 840c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 841fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 842fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 843fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 844fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 845515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 846ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 847ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 848ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 849ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 850515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 851515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 852515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 853515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 854515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 855515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 856515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 858ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 859ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 860ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 861ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 862ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 863ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 864ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 865ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 866ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 867ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 868ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 869ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 870aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 871ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 872ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 873ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 87416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 875ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 876ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 877ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 878b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 879ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 880ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 881ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 882b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 883ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 884ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 885ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 886515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 887515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 888515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 889515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 890515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 891b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 892515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 893515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 894515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 895515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 896515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 897515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 898515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 899515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 900515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 901515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 90218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 903515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 90483c4018fcca18fe9c281c3943fc58a17621636c4Jim Grosbach return Error(L, "unexpected token in .thumb_func directive"); 905642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach StringRef Name = Tok.getString(); 906b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 907515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 908515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 909b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 910515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 911642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 912642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 913642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 914515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 915515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 916515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 917515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 918515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 919515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 92018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 921515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 922515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 92338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 92458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 925b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 92658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 927b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 928515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 929515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 930515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 931515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 93218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 933b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 934515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 935515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 936515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 937515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 938515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 939515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 940515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 941515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 942515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 94318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 944515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 945515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 94618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 94758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 948b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 94958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 950b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 951515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 952515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 953515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 954515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 95518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 956b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 957515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 9582a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach if (Val == 16) 9592a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 9602a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach else 9612a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 9622a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 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