1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 3fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// The LLVM Compiler Infrastructure 4fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 5fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// This file is distributed under the University of Illinois Open Source 6fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// License. See LICENSE.TXT for details. 7fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 8fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//===----------------------------------------------------------------------===// 9fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 10fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h" 11ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h" 12ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/ADT/StringSwitch.h" 13ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h" 14ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h" 15ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h" 16ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h" 17ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h" 18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h" 19fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "llvm/MC/MCParser/MCAsmLexer.h" 2072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 2172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCTargetAsmParser.h" 22ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/Support/TargetRegistry.h" 23fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 24fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm; 25fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 26fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace { 27ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 28fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser { 2972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 30f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter enum FpFormatTy { 31f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_NONE = -1, 32f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_S, 33f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_D, 34f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_L, 35f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_W 36f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } FpFormat; 37f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 38ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCSubtargetInfo &STI; 39ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &Parser; 40ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 4172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER 4272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc" 4372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 44fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool MatchAndEmitInstruction(SMLoc IDLoc, 45fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 46fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola MCStreamer &Out); 47fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 48fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 49fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 50fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseInstruction(StringRef Name, SMLoc NameLoc, 5172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka SmallVectorImpl<MCParsedAsmOperand*> &Operands); 52fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 53f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool parseMathOperation(StringRef Name, SMLoc NameLoc, 54f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands); 55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 56fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseDirective(AsmToken DirectiveID); 57fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 58ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsAsmParser::OperandMatchResultTy 59ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*>&); 60038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 61ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned 62ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter getMCInstOperandNum(unsigned Kind, MCInst &Inst, 63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const SmallVectorImpl<MCParsedAsmOperand*> &Operands, 64ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned OperandNum, unsigned &NumMCOperands); 65ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 66ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 67ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic); 68ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 69ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int tryParseRegister(StringRef Mnemonic); 70ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 71ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 72ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic); 73ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter bool parseMemOffset(const MCExpr *&Res); 756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter bool parseRelocOperand(const MCExpr *&Res); 766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 77f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 78ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool isMips64() const { 79ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 80ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 81ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 82f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool isFP64() const { 83f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 84f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 85f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 86ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int matchRegisterName(StringRef Symbol); 87ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 88ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic); 89ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 90f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(FpFormatTy Format) { 91f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = Format; 92f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 93f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 94f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setDefaultFpFormat(); 95f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 96f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(StringRef Format); 97f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 98f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormatTy getFpFormat() {return FpFormat;} 99f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 100f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool requestsDoubleOperand(StringRef Mnemonic); 101f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 102ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned getReg(int RC,int RegNo); 103038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 104fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic: 105fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 106ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter : MCTargetAsmParser(), STI(sti), Parser(parser) { 107ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Initialize the set of available features. 108ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 109fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola } 110fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 111ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &getParser() const { return Parser; } 112ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmLexer &getLexer() const { return Parser.getLexer(); } 113ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 114fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}; 115fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 116fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 11772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace { 11872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 11972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine 12072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction. 12172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand { 122ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 12372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka enum KindTy { 12472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CondCode, 12572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CoprocNum, 12672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Immediate, 12772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Memory, 12872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_PostIndexRegister, 12972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Register, 13072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Token 13172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } Kind; 13272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 13372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 134ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 135ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter union { 136ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter struct { 137ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const char *Data; 138ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned Length; 139ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } Tok; 140ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 141ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter struct { 142ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned RegNum; 143ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } Reg; 144ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 145ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter struct { 146ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *Val; 147ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } Imm; 1486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter struct { 1506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter unsigned Base; 1516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Off; 1526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } Mem; 153ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter }; 154ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 155ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc StartLoc, EndLoc; 156ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 15772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic: 15872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addRegOperands(MCInst &Inst, unsigned N) const { 159ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 160ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateReg(getReg())); 16172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 162ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 16372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 164ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Add as immediate when possible. Null MCExpr = 0. 165ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Expr == 0) 166ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(0)); 167ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 168ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 169ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else 170ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateExpr(Expr)); 17172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 172ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 17372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addImmOperands(MCInst &Inst, unsigned N) const { 174ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 175ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *Expr = getImm(); 176ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter addExpr(Inst,Expr); 17772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 178ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 17972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addMemOperands(MCInst &Inst, unsigned N) const { 1806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert(N == 2 && "Invalid number of operands!"); 1816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Inst.addOperand(MCOperand::CreateReg(getMemBase())); 1836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Expr = getMemOff(); 1856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter addExpr(Inst,Expr); 18672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 18772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 18872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isReg() const { return Kind == k_Register; } 18972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isImm() const { return Kind == k_Immediate; } 19072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isToken() const { return Kind == k_Token; } 19172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isMem() const { return Kind == k_Memory; } 19272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 19372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka StringRef getToken() const { 19472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert(Kind == k_Token && "Invalid access!"); 195ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return StringRef(Tok.Data, Tok.Length); 19672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 19772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 19872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka unsigned getReg() const { 19972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert((Kind == k_Register) && "Invalid access!"); 200ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Reg.RegNum; 201ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 202ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 203ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *getImm() const { 204ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert((Kind == k_Immediate) && "Invalid access!"); 205ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Imm.Val; 206ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 207ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 2086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter unsigned getMemBase() const { 2096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 2106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Base; 2116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 2126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 2136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *getMemOff() const { 2146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 2156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Off; 2166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 2176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 218ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 219ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Token); 220ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Data = Str.data(); 221ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Length = Str.size(); 222ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 223ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = S; 224ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 225ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 226ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 227ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 228ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Register); 229ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Reg.RegNum = RegNum; 230ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 231ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 232ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 233ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 234ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 235ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 236ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Immediate); 237ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Imm.Val = Val; 238ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 239ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 240ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 24172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 24272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 2436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 2446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc S, SMLoc E) { 2456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand *Op = new MipsOperand(k_Memory); 2466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Base = Base; 2476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Off = Off; 2486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->StartLoc = S; 2496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->EndLoc = E; 2506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Op; 2516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 2526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 253ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getStartLoc - Get the location of the first token of this operand. 254ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc getStartLoc() const { return StartLoc; } 255ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getEndLoc - Get the location of the last token of this operand. 256ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc getEndLoc() const { return EndLoc; } 257ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 25872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka virtual void print(raw_ostream &OS) const { 25972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka llvm_unreachable("unimplemented!"); 26072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 26172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka}; 26272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka} 26372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 264038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosierunsigned MipsAsmParser:: 2655d637d7e93c1f6058c16b41b8ac7dd36c61b4a5cChad RosiergetMCInstOperandNum(unsigned Kind, MCInst &Inst, 266038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier const SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2672cc97def7434345e399e4f5f3f2001d6d7a93c6fChad Rosier unsigned OperandNum, unsigned &NumMCOperands) { 2685d637d7e93c1f6058c16b41b8ac7dd36c61b4a5cChad Rosier assert (0 && "getMCInstOperandNum() not supported by the Mips target."); 269efeaae8578ce9173a47f9e3fa5c44b90ae60c5abChad Rosier // The Mips backend doesn't currently include the matcher implementation, so 2705d637d7e93c1f6058c16b41b8ac7dd36c61b4a5cChad Rosier // the getMCInstOperandNumImpl() is undefined. This is a temporary 271efeaae8578ce9173a47f9e3fa5c44b90ae60c5abChad Rosier // work around. 2722cc97def7434345e399e4f5f3f2001d6d7a93c6fChad Rosier NumMCOperands = 0; 273038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier return 0; 274038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier} 275038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 276fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 277fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaMatchAndEmitInstruction(SMLoc IDLoc, 278fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 279fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola MCStreamer &Out) { 280ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCInst Inst; 281ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned ErrorInfo; 282ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned Kind; 283ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo); 284ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 285ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (MatchResult) { 286ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter default: break; 287ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_Success: { 288ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.setLoc(IDLoc); 289ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Out.EmitInstruction(Inst); 290ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 292ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MissingFeature: 293ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 294ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 295ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_InvalidOperand: { 296ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc ErrorLoc = IDLoc; 297ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo != ~0U) { 298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo >= Operands.size()) 299ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "too few operands for instruction"); 300ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 301ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc(); 302ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 303ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 304ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 305ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(ErrorLoc, "invalid operand for instruction"); 306ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MnemonicFail: 308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "invalid instruction"); 309ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 310fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 311fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 312fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 313ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::matchRegisterName(StringRef Name) { 314ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 315ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int CC = StringSwitch<unsigned>(Name) 316ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("zero", Mips::ZERO) 317ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("a0", Mips::A0) 318ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("a1", Mips::A1) 319ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("a2", Mips::A2) 320ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("a3", Mips::A3) 321ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("v0", Mips::V0) 322ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("v1", Mips::V1) 323ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s0", Mips::S0) 324ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s1", Mips::S1) 325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s2", Mips::S2) 326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s3", Mips::S3) 327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s4", Mips::S4) 328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s5", Mips::S5) 329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s6", Mips::S6) 330ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("s7", Mips::S7) 331ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("k0", Mips::K0) 332ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("k1", Mips::K1) 333ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("sp", Mips::SP) 334ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("fp", Mips::FP) 335ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("gp", Mips::GP) 336ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("ra", Mips::RA) 337ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t0", Mips::T0) 338ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t1", Mips::T1) 339ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t2", Mips::T2) 340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t3", Mips::T3) 341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t4", Mips::T4) 342ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t5", Mips::T5) 343ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t6", Mips::T6) 344ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t7", Mips::T7) 345ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t8", Mips::T8) 346ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("t9", Mips::T9) 347ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("at", Mips::AT) 348ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Case("fcc0", Mips::FCC0) 349ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter .Default(-1); 350ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 351ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (CC != -1) { 352ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //64 bit register in Mips are following 32 bit definitions. 353ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (isMips64()) 354ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter CC++; 355ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return CC; 356ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 357ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 358f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Name[0] == 'f') { 359f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef NumString = Name.substr(1); 360f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter unsigned IntVal; 361f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if( NumString.getAsInteger(10, IntVal)) 362f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; //not integer 363f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (IntVal > 31) 364f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 365f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 366f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormatTy Format = getFpFormat(); 367f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 368f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 369f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR32RegClassID, IntVal); 370f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_D) { 371f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if(isFP64()) { 372f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR64RegClassID, IntVal); 373f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 374f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //only even numbers available as register pairs 375f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (( IntVal > 31) || (IntVal%2 != 0)) 376f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 377f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::AFGR64RegClassID, IntVal/2); 378f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 379f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 380f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 381ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 382ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 383f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() { 384f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 385f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (isMips64() || isFP64()) 386f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_D; 387f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else 388f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_S; 389f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 390f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 391f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 392f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 393f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 394f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("ldxc1", true) 395f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("ldc1", true) 396f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("sdxc1", true) 397f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("sdc1", true) 398f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(false); 399f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 400f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return IsDouble; 401f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 402f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) { 403f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 404f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 405f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".s", FP_FORMAT_S) 406f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".d", FP_FORMAT_D) 407f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".l", FP_FORMAT_L) 408f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".w", FP_FORMAT_W) 409f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(FP_FORMAT_NONE); 410f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 411ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 412ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterunsigned MipsAsmParser::getReg(int RC,int RegNo){ 413ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); 414ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 415ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 416ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum,StringRef Mnemonic) { 417ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 418ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Mnemonic.lower() == "rdhwr") { 419ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //at the moment only hwreg29 is supported 420ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNum != 29) 421ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 422ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Mips::HWR29; 423ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 424ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 425ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNum > 31) 426ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 427ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 428ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return getReg(Mips::CPURegsRegClassID,RegNum); 429ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 430ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 431ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::tryParseRegister(StringRef Mnemonic) { 432ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const AsmToken &Tok = Parser.getTok(); 433ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNum = -1; 434ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 435ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Tok.is(AsmToken::Identifier)) { 436ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter std::string lowerCase = Tok.getString().lower(); 437ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter RegNum = matchRegisterName(lowerCase); 438ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } else if (Tok.is(AsmToken::Integer)) 4396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter RegNum = matchRegisterByNumber(static_cast<unsigned> (Tok.getIntVal()), 4406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Mnemonic.lower()); 441f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else 442f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return RegNum; //error 443f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64 444f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (isMips64() && RegNum == Mips::ZERO_64) { 445f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Mnemonic.find("ddiv") != StringRef::npos) 446f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter RegNum = Mips::ZERO; 447f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 448ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return RegNum; 449ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 450ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 451fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 452ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 453ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic){ 454ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 455ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 456ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNo = -1; 457f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 458f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //FIXME: we should make a more generic method for CCR 459f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if ((Mnemonic == "cfc1" || Mnemonic == "ctc1") 460f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter && Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){ 461f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter RegNo = Parser.getTok().getIntVal(); //get the int value 462f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //at the moment only fcc0 is supported 463f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (RegNo == 0) 464f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter RegNo = Mips::FCC0; 465f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } else 466f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter RegNo = tryParseRegister(Mnemonic); 467ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNo == -1) 468ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 469ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 470ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateReg(RegNo, S, 471f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.getTok().getLoc())); 472ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat register token. 473ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 474ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 475ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 476ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 477ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic) { 478ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //Check if the current operand has a custom associated parser, if so, try to 479ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //custom parse the operand, or fallback to the general approach. 480ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 481ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_Success) 482ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 483ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // If there wasn't a custom match, try the generic matcher below. Otherwise, 484ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // there was a match, but an error occurred, in which case, just return that 485ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // the operand parsing failed. 486ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_ParseFail) 487ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 488ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 489ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (getLexer().getKind()) { 490ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter default: 491ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 492ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 493ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Dollar: { 494ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //parse register 495ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 496ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat dollar token. 497ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //parse register operand 498ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (!tryParseRegisterOperand(Operands,Mnemonic)) { 499ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().is(AsmToken::LParen)) { 500ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //check if it is indexed addressing operand 501ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken("(", S)); 502ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); //eat parenthesis 503ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::Dollar)) 504ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 505ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 506ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); //eat dollar 507ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (tryParseRegisterOperand(Operands,Mnemonic)) 508ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 509ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 510ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (!getLexer().is(AsmToken::RParen)) 511ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 512ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 513ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter S = Parser.getTok().getLoc(); 514ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken(")", S)); 515ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); 516ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 517ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 518ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 519ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter //maybe it is a symbol reference 520ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Identifier; 521ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Parser.ParseIdentifier(Identifier)) 522ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 523ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 5246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 525ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 52638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 527ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 528ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Otherwise create a symbol ref. 5296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 530ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter getContext()); 531ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 532ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 533ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 534ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 535ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Identifier: 536ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::LParen: 537ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Minus: 538ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Plus: 539ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Integer: 540ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::String: { 541ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // quoted label names 542ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *IdVal; 543ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 544ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getParser().ParseExpression(IdVal)) 545ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 5466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 547ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 548ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 549ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 5506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Percent: { 5516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //it is a symbol reference or constant expression 5526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 5536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc S = Parser.getTok().getLoc(); //start location of the operand 5546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (parseRelocOperand(IdVal)) 5556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 5566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 5576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 5586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 5596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 5606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 5616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter }//case AsmToken::Percent 562ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter }//switch(getLexer().getKind()) 563fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 564fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 565fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 5666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 5676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 5686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); //eat % token 5696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &Tok = Parser.getTok(); //get next token, operation 5706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok.isNot(AsmToken::Identifier)) 5716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 5726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 57338539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer std::string Str = Tok.getIdentifier().str(); 5746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 5756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); //eat identifier 5766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //now make expression from the rest of the operand 5776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 5786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc EndLoc; 5796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 5806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::LParen) { 5816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter while (1) { 5826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); //eat '(' token 5836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::Percent) { 5846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); //eat % token 5856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &nextTok = Parser.getTok(); 5866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (nextTok.isNot(AsmToken::Identifier)) 5876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 58838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += "(%"; 58938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += nextTok.getIdentifier(); 5906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); //eat identifier 5916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() != AsmToken::LParen) 5926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 5936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 5946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter break; 5956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 5966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getParser().ParseParenExpression(IdVal,EndLoc)) 5976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 5986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 5996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter while (getLexer().getKind() == AsmToken::RParen) 6006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); //eat ')' token 6016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 6036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; //parenthesis must follow reloc operand 6046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //Check the type of the expression 60638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) { 6076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //it's a constant, evaluate lo or hi value 60838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer int Val = MCE->getValue(); 6096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Str == "lo") { 6106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Val = Val & 0xffff; 6116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else if (Str == "hi") { 6126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Val = (Val & 0xffff0000) >> 16; 6136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Res = MCConstantExpr::Create(Val, getContext()); 6156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 6166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 61838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) { 6196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //it's a symbol, create symbolic expression from symbol 62038539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer StringRef Symbol = MSRE->getSymbol().getName(); 6216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind VK = getVariantKind(Str); 6226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Res = MCSymbolRefExpr::Create(Symbol,VK,getContext()); 6236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 6246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 6266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 6276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 628ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 629ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc &EndLoc) { 630ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 631ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StartLoc = Parser.getTok().getLoc(); 632ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter RegNo = tryParseRegister(""); 633ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter EndLoc = Parser.getTok().getLoc(); 634ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return (RegNo == (unsigned)-1); 635ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 636ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 6376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { 6386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc S; 6406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter switch(getLexer().getKind()) { 6426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter default: 6436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 6446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Integer: 6456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Minus: 6466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Plus: 6476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return (getParser().ParseExpression(Res)); 648f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter case AsmToken::Percent: 6496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return parseRelocOperand(Res); 6506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::LParen: 6516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; //it's probably assuming 0 6526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 6546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 6556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 656ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 657ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 6586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal = 0; 6606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc S; 6616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //first operand is the offset 6626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter S = Parser.getTok().getLoc(); 6636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (parseMemOffset(IdVal)) 6656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 6666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &Tok = Parser.getTok(); //get next token 6686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok.isNot(AsmToken::LParen)) { 6696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "'(' expected"); 6706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 6716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); // Eat '(' token. 6746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &Tok1 = Parser.getTok(); //get next token 6766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok1.is(AsmToken::Dollar)) { 6776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); // Eat '$' token. 6786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (tryParseRegisterOperand(Operands,"")) { 6796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 6806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 6816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else { 6846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(),"unexpected token in operand"); 6856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 6866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6886b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &Tok2 = Parser.getTok(); //get next token 6896b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok2.isNot(AsmToken::RParen)) { 6906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "')' expected"); 6916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 6926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 6936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); // Eat ')' token. 6976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (IdVal == 0) 6996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter IdVal = MCConstantExpr::Create(0, getContext()); 7006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 7016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //now replace register operand with the mem operand 7026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 7036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter int RegNo = op->getReg(); 7046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //remove register from operands 7056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.pop_back(); 7066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter //and add memory operand 7076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 7086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter delete op; 709ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return MatchOperand_Success; 710ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 711ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 7126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 7136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 7146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind VK 7156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 7166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 7176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 7186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 7196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 7206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 7216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 7226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 7236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 7246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 7256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 7266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 7276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 7286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 7296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 7306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 7316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 7326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 7336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Default(MCSymbolRefExpr::VK_None); 7346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 7356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return VK; 7366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 7376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 7381ac4587eb32e639576973b793d465c5d9577bef7Benjamin Kramerstatic int ConvertCcString(StringRef CondString) { 739f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter int CC = StringSwitch<unsigned>(CondString) 740f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".f", 0) 741f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".un", 1) 742f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".eq", 2) 743f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ueq", 3) 744f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".olt", 4) 745f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ult", 5) 746f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ole", 6) 747f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ule", 7) 748f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".sf", 8) 749f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ngle", 9) 750f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".seq", 10) 751f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ngl", 11) 752f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".lt", 12) 753f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".nge", 13) 754f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".le", 14) 755f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ngt", 15) 756f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(-1); 757f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 758f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return CC; 759f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 760f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 761f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser:: 762f740d6e328bd10904b079e1ce6583f436d6c9817Jack CarterparseMathOperation(StringRef Name, SMLoc NameLoc, 763f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 764f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //split the format 765f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Start = Name.find('.'), Next = Name.rfind('.'); 766f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format1 = Name.slice(Start, Next); 767f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //and add the first format to the operands 768f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 769f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //now for the second format 770f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format2 = Name.slice(Next, StringRef::npos); 771f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 772f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 773f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //set the format for the first register 774f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format1); 775f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 776f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Read the remaining operands. 777f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 778f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Read the first operand. 779f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (ParseOperand(Operands, Name)) { 780f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 781f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.EatToEndOfStatement(); 782f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 783f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 784f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 785f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::Comma)) { 786f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 787f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.EatToEndOfStatement(); 788f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 789f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 790f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 791f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.Lex(); // Eat the comma. 792f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 793f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //set the format for the first register 794f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format2); 795f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 796f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Parse and remember the operand. 797f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (ParseOperand(Operands, Name)) { 798f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 799f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.EatToEndOfStatement(); 800f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 801f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 802f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 803f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 804f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 805f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 806f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.EatToEndOfStatement(); 807f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 808f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 809f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 810f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.Lex(); // Consume the EndOfStatement 811f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return false; 812f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 813f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 814fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 815fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaParseInstruction(StringRef Name, SMLoc NameLoc, 816fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 817f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //floating point instructions: should register be treated as double? 818f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (requestsDoubleOperand(Name)) { 819f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(FP_FORMAT_D); 820ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 821f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 822f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else { 823f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setDefaultFpFormat(); 824f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Create the leading tokens for the mnemonic, split by '.' characters. 825f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Start = 0, Next = Name.find('.'); 826f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Mnemonic = Name.slice(Start, Next); 827f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 828f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 829f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Next != StringRef::npos) { 831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //there is a format token in mnemonic 832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //StringRef Rest = Name.slice(Next, StringRef::npos); 833f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Dot = Name.find('.', Next+1); 834f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format = Name.slice(Next, Dot); 835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Dot == StringRef::npos) //only one '.' in a string, it's a format 836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else { 838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Name.startswith("c.")){ 839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // floating point compare, add '.' and immediate represent for cc 840f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 841f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter int Cc = ConvertCcString(Format); 842f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Cc == -1) { 843f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(NameLoc, "Invalid conditional code"); 844f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 845f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc E = SMLoc::getFromPointer( 846f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.getTok().getLoc().getPointer() -1 ); 847f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateImm( 848f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 849f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } else { 850f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //trunc, ceil, floor ... 851f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return parseMathOperation(Name, NameLoc, Operands); 852f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 853f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 854f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //the rest is a format 855f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Format = Name.slice(Dot, StringRef::npos); 856f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 857f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 858f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 859f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format); 860f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 861f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 862ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 863ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the remaining operands. 864ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 865ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the first operand. 866ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ParseOperand(Operands, Name)) { 867ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 868ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.EatToEndOfStatement(); 869ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 870ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 871ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 872ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter while (getLexer().is(AsmToken::Comma) ) { 873ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat the comma. 874ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 875ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Parse and remember the operand. 876ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ParseOperand(Operands, Name)) { 877ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 878ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.EatToEndOfStatement(); 879ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 880ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 881ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 882ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 884ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 885ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 886ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.EatToEndOfStatement(); 887ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 888ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 889ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 890ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Consume the EndOfStatement 891ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 892fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 893fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 894fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 895fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaParseDirective(AsmToken DirectiveID) { 896acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 897acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter if (DirectiveID.getString() == ".ent") { 898acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter //ignore this directive for now 899acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 900acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 901acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 902acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 903acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter if (DirectiveID.getString() == ".end") { 904acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter //ignore this directive for now 905acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 906acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 907acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 908acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 909acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter if (DirectiveID.getString() == ".frame") { 910acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter //ignore this directive for now 911acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.EatToEndOfStatement(); 912acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 913acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 914acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 915acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter if (DirectiveID.getString() == ".set") { 916acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter //ignore this directive for now 917acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.EatToEndOfStatement(); 918acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 919acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 920acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 921acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter if (DirectiveID.getString() == ".fmask") { 922acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter //ignore this directive for now 923acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.EatToEndOfStatement(); 924acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 925acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 926acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 927acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter if (DirectiveID.getString() == ".mask") { 928acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter //ignore this directive for now 929acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.EatToEndOfStatement(); 930acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 931acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 932acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 933acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter if (DirectiveID.getString() == ".gpword") { 934acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter //ignore this directive for now 935acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.EatToEndOfStatement(); 936acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 937acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 938acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 939fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 940fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 941fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 942fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() { 943fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 944fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 945fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 946fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 947fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 949ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER 950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION 951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc" 952