ARMAsmParser.cpp revision c6ef277a0b8f43af22d86aea9d5053749cacfbbb
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" 11c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 12c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 14ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 15ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 16ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 17ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h" 19c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/Compiler.h" 20c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 21c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 22c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 23ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbynamespace { 26ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbystruct ARMOperand; 27ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 28a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby// The shift types for register controlled shifts in arm memory addressing 29a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbyenum ShiftType { 30a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsl, 31a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Lsr, 32a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Asr, 33a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Ror, 34a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Rrx 35a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 36a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser { 38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 39ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 40ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyprivate: 41ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack); 50a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 51d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby bool ParseRegisterList(ARMOperand &Op); 52d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 53a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool ParseMemory(ARMOperand &Op); 54a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseMemoryOffsetReg(bool &Negative, 569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 6160131c0d0bb04d0ae3c13cbd055616c71d86e8eaKevin Enderby int &OffsetRegNum); 629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount); 64a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 65a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool ParseOperand(ARMOperand &Op); 66a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 67ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool ParseDirectiveWord(unsigned Size, SMLoc L); 68ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 69515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumb(SMLoc L); 70515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 71515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveThumbFunc(SMLoc L); 72515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 73515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveCode(SMLoc L); 74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool ParseDirectiveSyntax(SMLoc L); 76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 77a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // TODO - For now hacked versions of the next two are in here in this file to 78a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // allow some parser testing until the table gen versions are implemented. 79a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 80a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 81a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 829898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, 83a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby MCInst &Inst); 84a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 85d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby /// MatchRegisterName - Match the given string to a register name and return 86d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby /// its register number, or -1 if there is no match. To allow return values 87d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby /// to be used directly in register lists, arm registers have values between 88d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby /// 0 and 15. 89d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int MatchRegisterName(const StringRef &Name); 90a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 92a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 94ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 95ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby ARMAsmParser(const Target &T, MCAsmParser &_Parser) 96ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby : TargetAsmParser(T), Parser(_Parser) {} 97ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 98f007e853e26845cd6866b52d646455fc69f4e0afChris Lattner virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc, 999898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands); 100ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 101ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby virtual bool ParseDirective(AsmToken DirectiveID); 102ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 103ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 1067659389d0d4d315d30877592221da6a6f663114aChris Lattnerstruct ARMOperand : public MCParsedAsmOperand { 107a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum { 108a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Token, 109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Register, 110cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 111a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Memory 112a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 113a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 114a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 115a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 117a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 121a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 122a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 12399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback; 124a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 125a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 126cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby struct { 127cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 128cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 129cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // This is for all forms of ARM address expressions 131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned OffsetRegNum; // used when OffsetIsReg is true 1349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *Offset; // used when OffsetIsReg is false 135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; // used when OffsetRegShifted is true 1369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType ShiftType; // used when OffsetRegShifted is true 1379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby unsigned 1389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted : 1, // only used when OffsetIsReg is true 1399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Preindexed : 1, 1409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Postindexed : 1, 1419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg : 1, 1429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative : 1, // only used when OffsetIsReg is true 1439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback : 1; 144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 146a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 147a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 148a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 149a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 152a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Register && "Invalid access!"); 155a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Reg.RegNum; 156a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 157a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 158cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 159cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 160cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 161cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 162cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 163a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool isToken() const {return Kind == Token; } 164a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 165a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool isReg() const { return Kind == Register; } 166a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 167a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 168a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 169a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 171a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 172a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby static ARMOperand CreateToken(StringRef Str) { 173a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby ARMOperand Res; 174a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Kind = Token; 175a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Tok.Data = Str.data(); 176a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Tok.Length = Str.size(); 177a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Res; 178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 18099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby static ARMOperand CreateReg(unsigned RegNum, bool Writeback) { 181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby ARMOperand Res; 182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Kind = Register; 183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Reg.RegNum = RegNum; 18499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby Res.Reg.Writeback = Writeback; 185a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Res; 186a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 188cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby static ARMOperand CreateImm(const MCExpr *Val) { 189cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby ARMOperand Res; 190cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Res.Kind = Immediate; 191cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Res.Imm.Val = Val; 192cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Res; 193cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 194cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby static ARMOperand CreateMem(unsigned BaseRegNum, bool OffsetIsReg, 196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset, unsigned OffsetRegNum, 197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted, enum ShiftType ShiftType, 198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount, bool Preindexed, 199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed, bool Negative, bool Writeback) { 200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby ARMOperand Res; 201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Kind = Memory; 202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.BaseRegNum = BaseRegNum; 203a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.OffsetIsReg = OffsetIsReg; 204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.Offset = Offset; 205a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.OffsetRegNum = OffsetRegNum; 206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.OffsetRegShifted = OffsetRegShifted; 207a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.ShiftType = ShiftType; 208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.ShiftAmount = ShiftAmount; 209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.Preindexed = Preindexed; 210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.Postindexed = Postindexed; 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.Negative = Negative; 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Res.Mem.Writeback = Writeback; 213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Res; 214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 2209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and if it is a register name a Reg operand is created, the token is eaten 2219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// and false is returned. Else true is returned and no token is eaten. 2229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO this is likely to change to allow different register types and or to 2239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// parse for a specific register type. 2249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) { 22518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 226a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 227a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 228a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 229a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 230d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum; 231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 232a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby RegNum = MatchRegisterName(Tok.getString()); 233d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 235b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 236a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 23799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby bool Writeback = false; 2389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ParseWriteBack) { 23918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 2409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 2419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Writeback = true; 242b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 2439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 24499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 24599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 24699e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby Op = ARMOperand::CreateReg(RegNum, Writeback); 24799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a register list, return false if successful else return true or an 2529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// error. The first token must be a '{' when called. 253d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderbybool ARMAsmParser::ParseRegisterList(ARMOperand &Op) { 25418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 255cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby "Token is not an Left Curly Brace"); 256b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 257d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 25818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 259d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 260d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 261d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 262d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 263d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 264d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 265b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 266d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby unsigned RegList = 1 << RegNum; 267d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 268d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int HighRegNum = RegNum; 269d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby // TODO ranges like "{Rn-Rm}" 27018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan while (Parser.getTok().is(AsmToken::Comma)) { 271b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 272d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 27318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 274d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 275d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegTok.isNot(AsmToken::Identifier)) 276d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 277d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby int RegNum = MatchRegisterName(RegTok.getString()); 278d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegNum == -1) 279d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RegLoc, "register expected"); 280d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 281d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RegList & (1 << RegNum)) 282d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register duplicated in register list"); 283d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (RegNum <= HighRegNum) 284d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Warning(RegLoc, "register not in ascending order in register list"); 285d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby RegList |= 1 << RegNum; 286d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby HighRegNum = RegNum; 287d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 288b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 289d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby } 29018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 291d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (RCurlyTok.isNot(AsmToken::RCurly)) 292d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return Error(RCurlyTok.getLoc(), "'}' expected"); 293b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left curly brace token. 294d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 295d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return false; 296d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 297d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 2989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm memory expression, return false if successful else return true 2999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 3009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed 3019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do. 302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbybool ARMAsmParser::ParseMemory(ARMOperand &Op) { 30318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 3046bd266e56799703cd2773cadc4da8bc3c5107fdfKevin Enderby "Token is not an Left Bracket"); 305b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (BaseRegTok.isNot(AsmToken::Identifier)) 309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 3109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (MaybeParseRegister(Op, false)) 311a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(BaseRegTok.getLoc(), "register expected"); 3129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int BaseRegNum = Op.getReg(); 313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Preindexed = false; 315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Postindexed = false; 316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetIsReg = false; 317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Negative = false; 318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool Writeback = false; 319a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // First look for preindexed address forms, that is after the "[Rn" we now 3219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // have to see if the next token is a comma. 32218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.is(AsmToken::Comma)) { 324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed = true; 325b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 3269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby int OffsetRegNum; 3279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool OffsetRegShifted; 328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 3319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, 3329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Offset, OffsetIsReg, OffsetRegNum)) 3339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 33418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RBracTok = Parser.getTok(); 335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (RBracTok.isNot(AsmToken::RBrac)) 336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return Error(RBracTok.getLoc(), "']' expected"); 337b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 338a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 33918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &ExclaimTok = Parser.getTok(); 340a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ExclaimTok.is(AsmToken::Exclaim)) { 341a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 342b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat exclaim token 343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 344a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 345a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby OffsetRegShifted, ShiftType, ShiftAmount, 346a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed, Postindexed, Negative, Writeback); 347a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 348a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // The "[Rn" we have so far was not followed by a comma. 350a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (Tok.is(AsmToken::RBrac)) { 3519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // This is a post indexing addressing forms, that is a ']' follows after 3529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // the "[Rn". 353a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Postindexed = true; 354a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Writeback = true; 355b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 356a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 357e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby int OffsetRegNum = 0; 358a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby bool OffsetRegShifted = false; 359a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby enum ShiftType ShiftType; 360a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *ShiftAmount; 361a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const MCExpr *Offset; 362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 36318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 364e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::EndOfStatement)) { 365e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby if (NextTok.isNot(AsmToken::Comma)) 366e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby return Error(NextTok.getLoc(), "',' expected"); 367b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 3689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, 3699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby ShiftAmount, Offset, OffsetIsReg, OffsetRegNum)) 3709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 371a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 372e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 373a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, 374a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby OffsetRegShifted, ShiftType, ShiftAmount, 375a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Preindexed, Postindexed, Negative, Writeback); 376a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 379a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 380a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 381a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," 3839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is 3849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional): 3859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm 3869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// +/-Rm, shift 3879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// #offset 3889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise. 3899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative, 3909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetRegShifted, 3919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby enum ShiftType &ShiftType, 3929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&ShiftAmount, 3939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby const MCExpr *&Offset, 3949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby bool &OffsetIsReg, 39560131c0d0bb04d0ae3c13cbd055616c71d86e8eaKevin Enderby int &OffsetRegNum) { 3969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby ARMOperand Op; 3979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = false; 3989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = false; 3999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = false; 4009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = -1; 40118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &NextTok = Parser.getTok(); 4029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (NextTok.is(AsmToken::Plus)) 403b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat plus token. 4049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else if (NextTok.is(AsmToken::Minus)) { 4059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby Negative = true; 406b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat minus token 4079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 4089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // See if there is a register following the "[Rn," or "[Rn]," we have so far. 40918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &OffsetRegTok = Parser.getTok(); 4109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegTok.is(AsmToken::Identifier)) { 4119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetIsReg = !MaybeParseRegister(Op, false); 4129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetIsReg) 4139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegNum = Op.getReg(); 4149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 4159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // If we parsed a register as the offset then their can be a shift after that 4169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (OffsetRegNum != -1) { 4179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for a comma then a shift 41818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (Tok.is(AsmToken::Comma)) { 420b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat comma token. 4219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 42218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 4239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (ParseShift(ShiftType, ShiftAmount)) 4249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(Tok.getLoc(), "shift expected"); 4259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby OffsetRegShifted = true; 4269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 4279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 4289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" 4299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Look for #offset following the "[Rn," or "[Rn]," 43018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 4319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 4329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 433b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 4349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 4359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(Offset)) 4369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 4379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 4389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 4399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 4409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two: 442a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 444a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false. 4459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) { 44618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 447a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 448a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const StringRef &ShiftName = Tok.getString(); 450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 4519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsl; 452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 4539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Lsr; 454a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 4559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Asr; 456a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 4579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Ror; 458a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 4599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby St = Rrx; 460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 461a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 462b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 463a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Rrx stands alone. 4659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (St == Rrx) 4669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 467a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby // Otherwise, there must be a '#' and a shift amount. 46918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &HashTok = Parser.getTok(); 4709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (HashTok.isNot(AsmToken::Hash)) 4719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return Error(HashTok.getLoc(), "'#' expected"); 472b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat hash token. 4739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 4749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (getParser().ParseExpression(ShiftAmount)) 4759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return true; 476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 477a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 478a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 4809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// A hack to allow some testing, to be replaced by a real table gen version. 481d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderbyint ARMAsmParser::MatchRegisterName(const StringRef &Name) { 482d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby if (Name == "r0" || Name == "R0") 483d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 0; 484d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r1" || Name == "R1") 485a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return 1; 486d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r2" || Name == "R2") 487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return 2; 488d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r3" || Name == "R3") 489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return 3; 490d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r3" || Name == "R3") 491d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 3; 492d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r4" || Name == "R4") 493d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 4; 494d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r5" || Name == "R5") 495d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 5; 496d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r6" || Name == "R6") 497d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 6; 498d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r7" || Name == "R7") 499d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 7; 500d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r8" || Name == "R8") 501d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 8; 502d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r9" || Name == "R9") 503d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 9; 504d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r10" || Name == "R10") 505d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 10; 506d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r11" || Name == "R11" || Name == "fp") 507d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 11; 508d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r12" || Name == "R12" || Name == "ip") 509d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 12; 510d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r13" || Name == "R13" || Name == "sp") 51199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby return 13; 512d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r14" || Name == "R14" || Name == "lr") 513d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 14; 514d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby else if (Name == "r15" || Name == "R15" || Name == "pc") 515d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return 15; 516d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby return -1; 517a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 518a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// A hack to allow some testing, to be replaced by a real table gen version. 5209898671a74d3fc924347e679c45edaa685b3fe6eChris Lattnerbool ARMAsmParser:: 5219898671a74d3fc924347e679c45edaa685b3fe6eChris LattnerMatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands, 5229898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner MCInst &Inst) { 5239898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner ARMOperand &Op0 = *(ARMOperand*)Operands[0]; 524a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Op0.Kind == ARMOperand::Token && "First operand not a Token"); 525a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const StringRef &Mnemonic = Op0.getToken(); 526a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Mnemonic == "add" || 52799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby Mnemonic == "stmfd" || 52899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby Mnemonic == "str" || 52999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby Mnemonic == "ldmfd" || 530d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby Mnemonic == "ldr" || 531cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Mnemonic == "mov" || 532515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby Mnemonic == "sub" || 533515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby Mnemonic == "bl" || 534515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby Mnemonic == "push" || 535515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby Mnemonic == "blx" || 5362685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Mnemonic == "pop") { 5372685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar // Hard-coded to a valid instruction, till we have a real matcher. 5382685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Inst = MCInst(); 5392685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Inst.setOpcode(ARM::MOVr); 5402685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(2)); 5412685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(2)); 5422685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(0)); 5432685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Inst.addOperand(MCOperand::CreateImm(0)); 5442685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar Inst.addOperand(MCOperand::CreateReg(0)); 545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 5462685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar } 547a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 548a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 550a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 5529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 553a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderbybool ARMAsmParser::ParseOperand(ARMOperand &Op) { 554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 555a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::Identifier: 5569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby if (!MaybeParseRegister(Op, true)) 557a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 558515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 559515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 560515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 561515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 562515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return true; 563515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby Op = ARMOperand::CreateImm(IdVal); 564515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 565a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 566515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseMemory(Op); 567d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 568515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseRegisterList(Op); 569d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 570079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 571079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 572b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 573515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 574515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 575cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return true; 576515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby Op = ARMOperand::CreateImm(ImmVal); 577cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return false; 578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby default: 57918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in operand"); 580a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 581a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 582a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 5839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse an arm instruction mnemonic followed by its operands. 584f007e853e26845cd6866b52d646455fc69f4e0afChris Lattnerbool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc, 5859898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 5869898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name))); 587a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 58818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan SMLoc Loc = Parser.getTok().getLoc(); 589a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 590a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 591a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 5929898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner ARMOperand Op; 5939898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 5949898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner Operands.push_back(new ARMOperand(Op)); 595a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 596a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 597b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 598a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 599a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 6009898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner if (ParseOperand(Op)) return true; 6019898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner Operands.push_back(new ARMOperand(Op)); 602a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 603a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 6049898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 605ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 606ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 607515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives 608ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 609ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 610ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 611ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return ParseDirectiveWord(4, DirectiveID.getLoc()); 612515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 613515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumb(DirectiveID.getLoc()); 614515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 615515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveThumbFunc(DirectiveID.getLoc()); 616515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 617515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveCode(DirectiveID.getLoc()); 618515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 619515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return ParseDirectiveSyntax(DirectiveID.getLoc()); 620ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 621ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 622ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 623ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord 624ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 625ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 626ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 627ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 628ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 629ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 630ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 631ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 632aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 633ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 634ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 635ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 636ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 637ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 638ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 639ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 640b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 641ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 642ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 643ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 644b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 645ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 646ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 647ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 648515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb 649515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 650515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { 651515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 652515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 653b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 654515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 655515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 656515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 657515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 658515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 659515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 660515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 661515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc 662515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 663515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) { 66418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 665515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 666515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 66718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier(); 668b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Consume the identifier token. 669515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 670515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 671515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 672b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 673515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 674515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: mark symbol as a thumb symbol 675515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 676515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 677515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 678515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 679515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax 680515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) { 68218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 684515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 685515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const StringRef &Mode = Tok.getString(); 686515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool unified_syntax; 687515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Mode == "unified" || Mode == "UNIFIED") { 688b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 689515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby unified_syntax = true; 690515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby } 691515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (Mode == "divided" || Mode == "DIVIDED") { 692b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 693515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby unified_syntax = false; 694515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby } 695515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 696515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 697515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 698515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 69918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 700b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 701515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 702515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 703515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 704515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 705515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 706515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 707515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode 708515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 709515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) { 71018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 711515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 712515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 71318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 714515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby bool thumb_mode; 715515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Val == 16) { 716b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 717515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby thumb_mode = true; 718515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby } 719515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (Val == 32) { 720b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 721515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby thumb_mode = false; 722515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby } 723515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 724515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 725515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 726515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 72718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 728b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 729515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 730515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 731515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 732515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 733515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 734515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 7359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 736ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 737ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> X(TheARMTarget); 738ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget); 739ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 740