MipsAsmParser.cpp revision 25df6a93f3324bd30f44dcb95fd17aff0a92d438
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" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h" 19ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h" 20ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.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 { 2730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions { 2830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic: 2930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter MipsAssemblerOptions(): 3030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter aTReg(1), reorder(true), macro(true) { 3130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 3230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 3330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter unsigned getATRegNum() {return aTReg;} 3430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool setATReg(unsigned Reg); 35ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 3630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool isReorder() {return reorder;} 3730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setReorder() {reorder = true;} 3830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setNoreorder() {reorder = false;} 3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool isMacro() {return macro;} 4130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setMacro() {macro = true;} 4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setNomacro() {macro = false;} 4330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate: 4530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter unsigned aTReg; 4630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool reorder; 4730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool macro; 4830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}; 4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 5030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 5130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace { 52fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser { 5372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 54f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter enum FpFormatTy { 55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_NONE = -1, 56f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_S, 57f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_D, 58f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_L, 59f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_W 60f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } FpFormat; 61f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 62ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCSubtargetInfo &STI; 63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &Parser; 6410d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter MipsAssemblerOptions Options; 6530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 66ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 6772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER 6872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc" 6972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 7084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 71fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 7284125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 7384125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm); 74fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 75fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 76fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 776a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 786a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier SMLoc NameLoc, 7972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka SmallVectorImpl<MCParsedAsmOperand*> &Operands); 80fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 81f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool parseMathOperation(StringRef Name, SMLoc NameLoc, 82f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands); 83f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 84fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseDirective(AsmToken DirectiveID); 85fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 86ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsAsmParser::OperandMatchResultTy 87ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 88ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 89ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 90ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 91ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 92ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 93ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 94ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 95ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 96ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 97ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 98ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 99ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 101ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 102ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 103038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 104c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 105c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter unsigned RegisterClass); 106c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 107ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 108ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic); 109ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 110ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int tryParseRegister(bool is64BitReg); 111ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 112ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 113ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool is64BitReg); 114ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1159d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter bool needsExpansion(MCInst &Inst); 1169d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 1179d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter void expandInstruction(MCInst &Inst, SMLoc IDLoc, 1182490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 1199d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 1202490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 1212f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1222f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 1232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 12525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter void expandMemInst(MCInst &Inst, SMLoc IDLoc, 12625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions, 12725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool isLoad,bool isImmOpnd); 12830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool reportParseError(StringRef ErrorMsg); 12930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter bool parseMemOffset(const MCExpr *&Res); 131ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool parseRelocOperand(const MCExpr *&Res); 13230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 13330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseDirectiveSet(); 13430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 13530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetAtDirective(); 13630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoAtDirective(); 13730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetMacroDirective(); 13830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoMacroDirective(); 13930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetReorderDirective(); 14030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoReorderDirective(); 14130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 142c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter bool parseSetAssignment(); 143c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 144801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter bool parseDirectiveWord(unsigned Size, SMLoc L); 145801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 147f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 148ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool isMips64() const { 149ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 150ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 151ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 152f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool isFP64() const { 153f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 154f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 155f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 156ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int matchRegisterName(StringRef Symbol, bool is64BitReg); 157ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 15899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int matchCPURegisterName(StringRef Symbol); 15999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 160ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 161ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 162f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(FpFormatTy Format) { 163f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = Format; 164f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 165f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 166f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setDefaultFpFormat(); 167f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 168f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(StringRef Format); 169f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 170f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormatTy getFpFormat() {return FpFormat;} 171f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool requestsDoubleOperand(StringRef Mnemonic); 173f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 174ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter unsigned getReg(int RC,int RegNo); 175038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 17699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int getATReg(); 17725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 17825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool processInstruction(MCInst &Inst, SMLoc IDLoc, 17925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions); 180fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic: 181fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 182ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter : MCTargetAsmParser(), STI(sti), Parser(parser) { 183ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Initialize the set of available features. 184ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 185fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola } 186fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 187ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &getParser() const { return Parser; } 188ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmLexer &getLexer() const { return Parser.getLexer(); } 189ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 190fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}; 191fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 192fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 19372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace { 19472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 19572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine 19672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction. 19772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand { 198ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 199ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic: 200ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter enum RegisterKind { 201ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_None, 202ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_CPURegs, 203ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_CPU64Regs, 204ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_HWRegs, 205ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_HW64Regs, 206ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_FGR32Regs, 207ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_FGR64Regs, 20899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter Kind_AFGR64Regs, 209ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_CCRRegs 210ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter }; 211ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 212ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate: 21372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka enum KindTy { 21472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CondCode, 21572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CoprocNum, 21672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Immediate, 21772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Memory, 21872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_PostIndexRegister, 21972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Register, 22072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Token 22172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } Kind; 22272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 22372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 224ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 225a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token { 226a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const char *Data; 227a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Length; 228a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 229a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 230a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp { 231a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned RegNum; 232a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher RegisterKind Kind; 233a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 234a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 235a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp { 236a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Val; 237a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 238a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 239a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp { 240a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Base; 241a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Off; 242a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 243a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 244ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter union { 245a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token Tok; 246a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp Reg; 247a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp Imm; 248a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp Mem; 249ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter }; 250ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 251ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc StartLoc, EndLoc; 252ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 25372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic: 25472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addRegOperands(MCInst &Inst, unsigned N) const { 255ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 256ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateReg(getReg())); 25772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 258ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 25972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 260ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Add as immediate when possible. Null MCExpr = 0. 261ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Expr == 0) 262ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(0)); 263ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 264ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 265ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else 266ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateExpr(Expr)); 26772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 268ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 26972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addImmOperands(MCInst &Inst, unsigned N) const { 270ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 271ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *Expr = getImm(); 272ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter addExpr(Inst,Expr); 27372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 274ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 27572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addMemOperands(MCInst &Inst, unsigned N) const { 2766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert(N == 2 && "Invalid number of operands!"); 2776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 2786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Inst.addOperand(MCOperand::CreateReg(getMemBase())); 2796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 2806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Expr = getMemOff(); 2816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter addExpr(Inst,Expr); 28272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 28372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 28472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isReg() const { return Kind == k_Register; } 28572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isImm() const { return Kind == k_Immediate; } 28672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isToken() const { return Kind == k_Token; } 28772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isMem() const { return Kind == k_Memory; } 28872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 28972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka StringRef getToken() const { 29072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert(Kind == k_Token && "Invalid access!"); 291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return StringRef(Tok.Data, Tok.Length); 29272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 29372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 29472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka unsigned getReg() const { 29572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert((Kind == k_Register) && "Invalid access!"); 296ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Reg.RegNum; 297ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 299ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void setRegKind(RegisterKind RegKind) { 300ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Reg.Kind = RegKind; 302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 304ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *getImm() const { 305ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert((Kind == k_Immediate) && "Invalid access!"); 306ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Imm.Val; 307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 3096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter unsigned getMemBase() const { 3106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 3116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Base; 3126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 3146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *getMemOff() const { 3156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 3166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Off; 3176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 319ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 320ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Token); 321ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Data = Str.data(); 322ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Length = Str.size(); 323ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 324ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = S; 325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Register); 330ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Reg.RegNum = RegNum; 331ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 332ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 333ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 334ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 335ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 336ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 337ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Immediate); 338ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Imm.Val = Val; 339ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 34272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 34372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 3446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 3456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc S, SMLoc E) { 3466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand *Op = new MipsOperand(k_Memory); 3476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Base = Base; 3486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Off = Off; 3496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->StartLoc = S; 3506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->EndLoc = E; 3516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Op; 3526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 354ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isCPURegsAsm() const { 355a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi return Kind == k_Register && Reg.Kind == Kind_CPURegs; 356ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 357ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const { 358ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 359ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 360ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 361ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isCPU64RegsAsm() const { 362a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi return Kind == k_Register && Reg.Kind == Kind_CPU64Regs; 363ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 364ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const { 365ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 366ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 367ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 368ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isHWRegsAsm() const { 369ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 370ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_HWRegs; 371ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 372ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const { 373ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 374ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 375ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 376ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isHW64RegsAsm() const { 377ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 378ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_HW64Regs; 379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const { 381ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 382ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 383ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addCCRAsmOperands(MCInst &Inst, unsigned N) const { 385ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 386ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 388ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isCCRAsm() const { 389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_CCRRegs; 391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 392ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 393ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getStartLoc - Get the location of the first token of this operand. 394ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc getStartLoc() const { return StartLoc; } 395ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getEndLoc - Get the location of the last token of this operand. 396ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc getEndLoc() const { return EndLoc; } 397ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 39872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka virtual void print(raw_ostream &OS) const { 39972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka llvm_unreachable("unimplemented!"); 40072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 40172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka}; 40272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka} 40372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 40425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm { 40525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[]; 40625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 40725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 40825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return MipsInsts[Opcode]; 40925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 41025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 41125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 41225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions) { 41325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 41425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Inst.setLoc(IDLoc); 41525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MCID.mayLoad() || MCID.mayStore()) { 41625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Check the offset of memory operand, if it is a symbol 41725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // reference or immediate we may have to expand instructions 41825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter for (unsigned i=0;i<MCID.getNumOperands();i++) { 41925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 42025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 42125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 42225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCOperand &Op = Inst.getOperand(i); 42325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (Op.isImm()) { 42425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter int MemOffset = Op.getImm(); 42525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MemOffset < -32768 || MemOffset > 32767) { 42625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Offset can't exceed 16bit value 42725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter expandMemInst(Inst,IDLoc,Instructions,MCID.mayLoad(),true); 42825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 42925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 43025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } else if (Op.isExpr()) { 43125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *Expr = Op.getExpr(); 43225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (Expr->getKind() == MCExpr::SymbolRef){ 43325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR = 43425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter static_cast<const MCSymbolRefExpr*>(Expr); 43525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (SR->getKind() == MCSymbolRefExpr::VK_None) { 43625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Expand symbol 43725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter expandMemInst(Inst,IDLoc,Instructions,MCID.mayLoad(),false); 43825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 43925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 44025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 44125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 44225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 44325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 44425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 44525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 44625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (needsExpansion(Inst)) 44725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter expandInstruction(Inst, IDLoc, Instructions); 44825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else 44925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(Inst); 45025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 45125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 45225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 45325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 4549d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) { 4559d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 4569d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter switch(Inst.getOpcode()) { 4579d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter case Mips::LoadImm32Reg: 4582f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter case Mips::LoadAddr32Imm: 4592f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter case Mips::LoadAddr32Reg: 4609d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter return true; 4619d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter default: 4629d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter return false; 4639d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 4649d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 4652490dc650895149423bb59538dc03ca352222702Jack Carter 4669d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 4672490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions){ 4689d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter switch(Inst.getOpcode()) { 4699d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter case Mips::LoadImm32Reg: 4709d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter return expandLoadImm(Inst, IDLoc, Instructions); 4712f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter case Mips::LoadAddr32Imm: 4722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter return expandLoadAddressImm(Inst,IDLoc,Instructions); 4732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter case Mips::LoadAddr32Reg: 4742f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter return expandLoadAddressReg(Inst,IDLoc,Instructions); 4759d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 4769d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 4772490dc650895149423bb59538dc03ca352222702Jack Carter 4789d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 4792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions){ 4802490dc650895149423bb59538dc03ca352222702Jack Carter MCInst tmpInst; 4819d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &ImmOp = Inst.getOperand(1); 4822f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 4839d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &RegOp = Inst.getOperand(0); 4849d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter assert(RegOp.isReg() && "expected register operand kind"); 4859d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 4869d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter int ImmValue = ImmOp.getImm(); 4872490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.setLoc(IDLoc); 4889d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter if ( 0 <= ImmValue && ImmValue <= 65535) { 4892490dc650895149423bb59538dc03ca352222702Jack Carter // for 0 <= j <= 65535. 4909d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => ori d,$zero,j 491ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 4922490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 4932490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand( 494ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MCOperand::CreateReg(Mips::ZERO)); 4952490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 4969d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 4979d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } else if ( ImmValue < 0 && ImmValue >= -32768) { 4982490dc650895149423bb59538dc03ca352222702Jack Carter // for -32768 <= j < 0. 4999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => addiu d,$zero,j 500ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5012490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5022490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand( 503ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MCOperand::CreateReg(Mips::ZERO)); 5042490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5059d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5069d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } else { 5079d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // for any other value of j that is representable as a 32-bit integer. 5089d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => lui d,hi16(j) 5092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter // ori d,d,lo16(j) 510ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5112490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5122490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 5139d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5142490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.clear(); 515ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5162490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5172490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5182490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 5192490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.setLoc(IDLoc); 5209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5219d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 5229d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 5232490dc650895149423bb59538dc03ca352222702Jack Carter 5242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 5252f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions){ 5262f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 5272f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(2); 5282f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 5292f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &SrcRegOp = Inst.getOperand(1); 5302f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(SrcRegOp.isReg() && "expected register operand kind"); 5312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &DstRegOp = Inst.getOperand(0); 5322f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(DstRegOp.isReg() && "expected register operand kind"); 5332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 5342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter if ( -32768 <= ImmValue && ImmValue <= 65535) { 5352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //for -32768 <= j <= 65535. 5362f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //la d,j(s) => addiu d,s,j 537ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 5402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5412f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5422f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 5432f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //for any other value of j that is representable as a 32-bit integer. 5442f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //la d,j(s) => lui d,hi16(j) 5452f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter // ori d,d,lo16(j) 5462f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter // addu d,d,s 547ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5482f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5492f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 5502f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5512f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 552ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5532f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5542f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5552f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 5562f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5572f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 5582f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDu); 5592f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5602f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5612f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 5622f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5632f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 5642f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 5652f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 5662f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 5672f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions){ 5682f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 5692f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(1); 5702f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 5712f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &RegOp = Inst.getOperand(0); 5722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(RegOp.isReg() && "expected register operand kind"); 5732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 5742f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter if ( -32768 <= ImmValue && ImmValue <= 65535) { 5752f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //for -32768 <= j <= 65535. 5762f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //la d,j => addiu d,$zero,j 5772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand( 580ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MCOperand::CreateReg(Mips::ZERO)); 5812f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5822f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5832f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 5842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //for any other value of j that is representable as a 32-bit integer. 5852f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter //la d,j => lui d,hi16(j) 5862f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter // ori d,d,lo16(j) 587ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5882f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5892f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 5902f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5912f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 592ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5932f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5942f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5952f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 5962f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5972f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 5982f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 5992f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 60025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 60125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions, 60225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool isLoad,bool isImmOpnd) { 60325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR; 60425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCInst TempInst; 60525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned ImmOffset,HiOffset,LoOffset; 60625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *ExprOffset; 60725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned TmpRegNum; 60825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID: 60925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Mips::CPURegsRegClassID, 61025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter getATReg()); 61125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // 1st operand is either source or dst register 61225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 61325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned RegOpNum = Inst.getOperand(0).getReg(); 61425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // 2nd operand is base register 61525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 61625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned BaseRegNum = Inst.getOperand(1).getReg(); 61725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // 3rd operand is either immediate or expression 61825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) { 61925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 62025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ImmOffset = Inst.getOperand(2).getImm(); 62125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter LoOffset = ImmOffset & 0x0000ffff; 62225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset = (ImmOffset & 0xffff0000) >> 16; 62325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // If msb of LoOffset is 1(negative number) we must increment HiOffset 62425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (LoOffset & 0x8000) 62525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset++; 62625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 62725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else 62825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ExprOffset = Inst.getOperand(2).getExpr(); 62925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // All instructions will have the same location 63025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setLoc(IDLoc); 63125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // 1st instruction in expansion is LUi. For load instruction we can use 63225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // the dst register as a temporary if base and dst are different, 63325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // but for stores we must use $at 63425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TmpRegNum = (isLoad && (BaseRegNum != RegOpNum))?RegOpNum:AtRegNum; 63525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::LUi); 63625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 63725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 63825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 63925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 64025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 64125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SR = static_cast<const MCSymbolRefExpr*>(ExprOffset); 64225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr:: 64325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Create(SR->getSymbol().getName(), 64425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCSymbolRefExpr::VK_Mips_ABS_HI, 64525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter getContext()); 64625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 64725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 64825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 64925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Add the instruction to the list 65025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 65125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // and prepare TempInst for next instruction 65225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 65325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // which is add temp register to base 65425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::ADDu); 65525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 65625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 65725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 65825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 65925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 66025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // and finaly, create original instruction with low part 66125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // of offset and new base 66225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Inst.getOpcode()); 66325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 66425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 66525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 66625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 66725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 66825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 66925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr:: 67025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Create(SR->getSymbol().getName(), 67125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCSymbolRefExpr::VK_Mips_ABS_LO, 67225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter getContext()); 67325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 67425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 67525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 67625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 67725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 67825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 67925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 680fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 68184125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 682fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 68384125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 68484125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm) { 685ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCInst Inst; 68625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVector<MCInst, 8> Instructions; 6876e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 68884125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MatchingInlineAsm); 689ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 690ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (MatchResult) { 691ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter default: break; 692ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_Success: { 69325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (processInstruction(Inst,IDLoc,Instructions)) 69425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return true; 69525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter for(unsigned i =0; i < Instructions.size(); i++) 69625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Out.EmitInstruction(Instructions[i]); 697ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 698ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 699ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MissingFeature: 700ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 701ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 702ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_InvalidOperand: { 703ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc ErrorLoc = IDLoc; 704ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo != ~0U) { 705ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo >= Operands.size()) 706ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "too few operands for instruction"); 707ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 708ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc(); 709ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 710ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 711ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 712ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(ErrorLoc, "invalid operand for instruction"); 713ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 714ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MnemonicFail: 715ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "invalid instruction"); 716ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 717fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 718fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 719fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 72099e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) { 721572e1bd109518f80b54d229de10699c4603944c3David Chisnall int CC; 72299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 72399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (Name == "at") 72499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return getATReg(); 72599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 726572e1bd109518f80b54d229de10699c4603944c3David Chisnall CC = StringSwitch<unsigned>(Name) 72799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("zero", 0) 72899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a0", 4) 72999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a1", 5) 73099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a2", 6) 73199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a3", 7) 73299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("v0", 2) 73399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("v1", 3) 73499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s0", 16) 73599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s1", 17) 73699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s2", 18) 73799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s3", 19) 73899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s4", 20) 73999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s5", 21) 74099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s6", 22) 74199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s7", 23) 74299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("k0", 26) 74399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("k1", 27) 74499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("sp", 29) 74599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("fp", 30) 74699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("gp", 28) 74799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("ra", 31) 74899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t0", 8) 74999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t1", 9) 75099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t2", 10) 75199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t3", 11) 75299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t4", 12) 75399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t5", 13) 75499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t6", 14) 75599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t7", 15) 75699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t8", 24) 75799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t9", 25) 75899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Default(-1); 75999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 76099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter // Although SGI documentation just cut out t0-t3 for n32/n64, 76199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 76299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 76399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (isMips64() && 8 <= CC && CC <= 11) 76499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter CC += 4; 76599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 76699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (CC == -1 && isMips64()) 767572e1bd109518f80b54d229de10699c4603944c3David Chisnall CC = StringSwitch<unsigned>(Name) 76899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a4", 8) 76999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a5", 9) 77099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a6", 10) 77199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a7", 11) 77299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("kt0", 26) 77399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("kt1", 27) 77499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s8", 30) 775572e1bd109518f80b54d229de10699c4603944c3David Chisnall .Default(-1); 776572e1bd109518f80b54d229de10699c4603944c3David Chisnall 77799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return CC; 77899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter} 77999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 78099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 78199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int CC; 78299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter CC = matchCPURegisterName(Name); 783572e1bd109518f80b54d229de10699c4603944c3David Chisnall if (CC != -1) 78499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return matchRegisterByNumber(CC,is64BitReg?Mips::CPU64RegsRegClassID: 78599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter Mips::CPURegsRegClassID); 786ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 787f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Name[0] == 'f') { 788f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef NumString = Name.substr(1); 789f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter unsigned IntVal; 790f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if( NumString.getAsInteger(10, IntVal)) 7919d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter return -1; // not integer 792f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (IntVal > 31) 793f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 794f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 795f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormatTy Format = getFpFormat(); 796f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 797f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 798f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR32RegClassID, IntVal); 799f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_D) { 800f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if(isFP64()) { 801f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR64RegClassID, IntVal); 802f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 8039d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // only even numbers available as register pairs 804f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (( IntVal > 31) || (IntVal%2 != 0)) 805f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 806f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::AFGR64RegClassID, IntVal/2); 807f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 808f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 809f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 810ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 811ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 812f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() { 813f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 814f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (isMips64() || isFP64()) 815f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_D; 816f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else 817f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_S; 818f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 819f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 820f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 821f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 822f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 823f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("ldxc1", true) 824f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("ldc1", true) 825f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("sdxc1", true) 826f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("sdc1", true) 827f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(false); 828f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 829f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return IsDouble; 830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) { 832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 833f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 834f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".s", FP_FORMAT_S) 835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".d", FP_FORMAT_D) 836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".l", FP_FORMAT_L) 837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".w", FP_FORMAT_W) 838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(FP_FORMAT_NONE); 839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 840ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 84130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) { 84230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Reg > 31) 84330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 84430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 84530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter aTReg = Reg; 84630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 84730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 84830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 84999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::getATReg() { 85099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return Options.getATRegNum(); 85130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 85230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 85330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterunsigned MipsAsmParser::getReg(int RC,int RegNo) { 854ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); 855ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 856ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 857ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 858ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 859ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNum > 31) 860ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 861ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 862ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return getReg(RegClass, RegNum); 863ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 864ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 865ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::tryParseRegister(bool is64BitReg) { 866ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const AsmToken &Tok = Parser.getTok(); 867ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNum = -1; 868ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 869ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Tok.is(AsmToken::Identifier)) { 870ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter std::string lowerCase = Tok.getString().lower(); 871ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNum = matchRegisterName(lowerCase, is64BitReg); 872ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } else if (Tok.is(AsmToken::Integer)) 8739d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 874ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter is64BitReg ? Mips::CPU64RegsRegClassID 875ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter : Mips::CPURegsRegClassID); 876ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return RegNum; 877ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 878ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 879fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 880ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 881ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool is64BitReg){ 882ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 884ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNo = -1; 885f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 886ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNo = tryParseRegister(is64BitReg); 887ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNo == -1) 888ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 889ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 890ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(MipsOperand::CreateReg(RegNo, S, 891ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.getTok().getLoc())); 892ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat register token. 893ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 894ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 895ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 896ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 897ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic) { 8989d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // Check if the current operand has a custom associated parser, if so, try to 8999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // custom parse the operand, or fallback to the general approach. 900ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 901ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_Success) 902ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 903ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // If there wasn't a custom match, try the generic matcher below. Otherwise, 904ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // there was a match, but an error occurred, in which case, just return that 905ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // the operand parsing failed. 906ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_ParseFail) 907ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 908ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 909ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (getLexer().getKind()) { 910ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter default: 911ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 912ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Dollar: { 9149d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // parse register 915ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 916ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat dollar token. 9179d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // parse register operand 918ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (!tryParseRegisterOperand(Operands, isMips64())) { 919ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().is(AsmToken::LParen)) { 9209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // check if it is indexed addressing operand 921ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken("(", S)); 9229d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Parser.Lex(); // eat parenthesis 923ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::Dollar)) 924ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 925ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 9269d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Parser.Lex(); // eat dollar 927ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (tryParseRegisterOperand(Operands, isMips64())) 928ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 929ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 930ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (!getLexer().is(AsmToken::RParen)) 931ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 932ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 933ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter S = Parser.getTok().getLoc(); 934ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken(")", S)); 935ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); 936ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 937ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 938ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 9399d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // maybe it is a symbol reference 940ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Identifier; 941cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (Parser.parseIdentifier(Identifier)) 942ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 943ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 944ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 945ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 94638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 947ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Otherwise create a symbol ref. 9496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter getContext()); 951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 952ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 953ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 954ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 955ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Identifier: 956c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // Look for the existing symbol, we should check if 957c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // we need to assigne the propper RegisterKind 958c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (searchSymbolAlias(Operands,MipsOperand::Kind_None)) 959c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 960c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter //else drop to expression parsing 961ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::LParen: 962ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Minus: 963ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Plus: 964ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Integer: 965ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::String: { 966ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // quoted label names 967ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *IdVal; 968ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 969cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(IdVal)) 970ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 971ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 972ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 973ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 974ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 9756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Percent: { 9769d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // it is a symbol reference or constant expression 9776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 9789d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter SMLoc S = Parser.getTok().getLoc(); // start location of the operand 979ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (parseRelocOperand(IdVal)) 9806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 9816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 982ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 983ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 9846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 9856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 98630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // case AsmToken::Percent 98730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // switch(getLexer().getKind()) 988fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 989fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 990fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 991ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 9926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 99330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // eat % token 9949d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const AsmToken &Tok = Parser.getTok(); // get next token, operation 9956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok.isNot(AsmToken::Identifier)) 9966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 9976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 99838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer std::string Str = Tok.getIdentifier().str(); 9996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 10009d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Parser.Lex(); // eat identifier 100130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // now make expression from the rest of the operand 10026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 1003ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc EndLoc; 10046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 10056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::LParen) { 10066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter while (1) { 100730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // eat '(' token 10086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::Percent) { 100930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // eat % token 10106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &nextTok = Parser.getTok(); 10116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (nextTok.isNot(AsmToken::Identifier)) 10126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 101338539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += "(%"; 101438539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += nextTok.getIdentifier(); 101530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // eat identifier 10166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() != AsmToken::LParen) 10176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 10186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 10196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter break; 10206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 1021cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseParenExpression(IdVal,EndLoc)) 10226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 10236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1024ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter while (getLexer().getKind() == AsmToken::RParen) 102530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // eat ')' token 10266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 10276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 102830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; // parenthesis must follow reloc operand 10296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 103030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // Check the type of the expression 103138539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) { 103225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // It's a constant, evaluate lo or hi value 10336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Str == "lo") { 103425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter short Val = MCE->getValue(); 103525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Res = MCConstantExpr::Create(Val, getContext()); 10366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else if (Str == "hi") { 103725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter int Val = MCE->getValue(); 103877217229ba1bbc92f3a53099fa91bcdaa7797da8Jack Carter int LoSign = Val & 0x8000; 10396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Val = (Val & 0xffff0000) >> 16; 104025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Lower part is treated as a signed int, so if it is negative 104125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // we must add 1 to the hi part to compensate 104277217229ba1bbc92f3a53099fa91bcdaa7797da8Jack Carter if (LoSign) 104377217229ba1bbc92f3a53099fa91bcdaa7797da8Jack Carter Val++; 104425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Res = MCConstantExpr::Create(Val, getContext()); 10456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 10466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 10476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 10486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 104938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) { 105025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // It's a symbol, create symbolic expression from symbol 105138539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer StringRef Symbol = MSRE->getSymbol().getName(); 10526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind VK = getVariantKind(Str); 10536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Res = MCSymbolRefExpr::Create(Symbol,VK,getContext()); 10546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 10556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 10566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 10576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 10586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1059ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1060ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc &EndLoc) { 1061ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1062ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StartLoc = Parser.getTok().getLoc(); 1063ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNo = tryParseRegister(isMips64()); 1064ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter EndLoc = Parser.getTok().getLoc(); 1065ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return (RegNo == (unsigned)-1); 1066ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1067ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 10686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { 1069ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1070ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 1071ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 10726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter switch(getLexer().getKind()) { 10736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter default: 10746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 107525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter case AsmToken::Identifier: 10766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Integer: 10776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Minus: 10786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Plus: 1079cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach return (getParser().parseExpression(Res)); 1080ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter case AsmToken::Percent: 1081ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return parseRelocOperand(Res); 10826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::LParen: 108330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; // it's probably assuming 0 10846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 10856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 10866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 10876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1088ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 1089ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 10906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 10916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal = 0; 1092ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 1093ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // first operand is the offset 1094ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter S = Parser.getTok().getLoc(); 10956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 10966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (parseMemOffset(IdVal)) 10976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 10986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 109930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter const AsmToken &Tok = Parser.getTok(); // get next token 11006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok.isNot(AsmToken::LParen)) { 11012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 11022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter if (Mnemonic->getToken() == "la") { 1103ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1); 11042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 11052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter return MatchOperand_Success; 11062f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 11076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "'(' expected"); 11086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 11096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 11106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); // Eat '(' token. 11126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11132f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const AsmToken &Tok1 = Parser.getTok(); // get next token 11146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok1.is(AsmToken::Dollar)) { 11156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); // Eat '$' token. 1116ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (tryParseRegisterOperand(Operands, isMips64())) { 11176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 11186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 11196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 11206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else { 112230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 11236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 11246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 11256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 112630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter const AsmToken &Tok2 = Parser.getTok(); // get next token 11276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok2.isNot(AsmToken::RParen)) { 11286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "')' expected"); 11296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 11306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 11316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1132ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1133ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 11346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Parser.Lex(); // Eat ')' token. 11356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (IdVal == 0) 11376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter IdVal = MCConstantExpr::Create(0, getContext()); 11386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 113930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // now replace register operand with the mem operand 11406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 11416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter int RegNo = op->getReg(); 114230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // remove register from operands 11436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.pop_back(); 114430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // and add memory operand 11456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 11466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter delete op; 1147ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return MatchOperand_Success; 1148ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1149ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1150ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1151ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1152ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1153ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (!isMips64()) 1154ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1155c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().getKind() == AsmToken::Identifier) { 1156c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (searchSymbolAlias(Operands,MipsOperand::Kind_CPU64Regs)) 1157c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_Success; 1158c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_NoMatch; 1159c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1160ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // if the first token is not '$' we have an error 1161ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1162ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1163ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1164ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1165ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if(!tryParseRegisterOperand(Operands, true)) { 1166ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // set the proper register kind 1167ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1168ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_CPU64Regs); 1169ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1170ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 1171ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1172ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1173ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1174c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser:: 1175c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack CartersearchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1176c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter unsigned RegisterKind) { 1177c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1178c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1179c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Sym) { 1180c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter SMLoc S = Parser.getTok().getLoc(); 1181c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCExpr *Expr; 1182c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Sym->isVariable()) 1183c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Expr = Sym->getVariableValue(); 1184c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter else 1185c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1186c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Expr->getKind() == MCExpr::SymbolRef) { 1187c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1188c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const StringRef DefSymbol = Ref->getSymbol().getName(); 1189c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (DefSymbol.startswith("$")) { 1190c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // Lookup for the register with corresponding name 1191c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter int RegNum = matchRegisterName(DefSymbol.substr(1),isMips64()); 1192c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (RegNum > -1) { 1193c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.Lex(); 1194c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MipsOperand *op = MipsOperand::CreateReg(RegNum,S, 1195c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.getTok().getLoc()); 1196c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter op->setRegKind((MipsOperand::RegisterKind)RegisterKind); 1197c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Operands.push_back(op); 1198c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return true; 1199c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1200c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1201c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } else if (Expr->getKind() == MCExpr::Constant) { 1202c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.Lex(); 1203c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 1204c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MipsOperand *op = MipsOperand::CreateImm(Const,S, 1205c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.getTok().getLoc()); 1206c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Operands.push_back(op); 1207c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return true; 1208c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1209c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1210c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1211c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter} 1212ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1213ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1214ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1215c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().getKind() == AsmToken::Identifier) { 1216c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (searchSymbolAlias(Operands,MipsOperand::Kind_CPURegs)) 1217c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_Success; 1218c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_NoMatch; 1219c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1220ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // if the first token is not '$' we have an error 1221ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1222ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1223ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1224ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1225ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if(!tryParseRegisterOperand(Operands, false)) { 1226ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // set the propper register kind 1227ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1228ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_CPURegs); 1229ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1230ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 1231ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1232ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1233ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1234ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1235ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1236ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1237c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter if (isMips64()) 1238c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter return MatchOperand_NoMatch; 1239c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter 1240ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // if the first token is not '$' we have error 1241ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1242ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1243ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 1244ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1245ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1246ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter const AsmToken &Tok = Parser.getTok(); // get next token 1247ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.isNot(AsmToken::Integer)) 1248ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1249ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1250ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum = Tok.getIntVal(); 1251ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // at the moment only hwreg29 is supported 1252ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 29) 1253ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1254ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1255ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 1256ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.getTok().getLoc()); 1257ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_HWRegs); 1258ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1259ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1260ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat reg number 1261ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1262ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1263ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1264ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1265ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1266c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter 1267c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter if (!isMips64()) 1268c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter return MatchOperand_NoMatch; 1269ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter //if the first token is not '$' we have error 1270ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1271ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1272ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 1273ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1274ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1275ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter const AsmToken &Tok = Parser.getTok(); // get next token 1276ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.isNot(AsmToken::Integer)) 1277ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1278ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1279ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum = Tok.getIntVal(); 1280ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // at the moment only hwreg29 is supported 1281ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 29) 1282ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1283ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1284ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 1285ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.getTok().getLoc()); 1286c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter op->setRegKind(MipsOperand::Kind_HW64Regs); 1287ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1288ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1289ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat reg number 1290ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1291ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1292ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1293ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1294ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1295ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum; 1296ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter //if the first token is not '$' we have error 1297ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1298ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1299ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 1300ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter const AsmToken &Tok = Parser.getTok(); // get next token 1303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.is(AsmToken::Integer)) { 1304ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNum = Tok.getIntVal(); 1305ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // at the moment only fcc0 is supported 1306ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 0) 1307ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1308ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } else if (Tok.is(AsmToken::Identifier)) { 1309ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter // at the moment only fcc0 is supported 1310ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.getIdentifier() != "fcc0") 1311ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1312ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } else 1313ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1314ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1315ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 1316ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.getTok().getLoc()); 1317ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_CCRRegs); 1318ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1319ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1320ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat reg number 1321ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1322ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1323ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 13246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 13256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 13266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind VK 13276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 13286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 13296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 13306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 13316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 13326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 13336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 13346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 13356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 13366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 13376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 13386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 13396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 13406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 13416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 13426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 13436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 13446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 13456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Default(MCSymbolRefExpr::VK_None); 13466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 13476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return VK; 13486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 13496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 13501ac4587eb32e639576973b793d465c5d9577bef7Benjamin Kramerstatic int ConvertCcString(StringRef CondString) { 1351f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter int CC = StringSwitch<unsigned>(CondString) 1352f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".f", 0) 1353f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".un", 1) 1354f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".eq", 2) 1355f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ueq", 3) 1356f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".olt", 4) 1357f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ult", 5) 1358f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ole", 6) 1359f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ule", 7) 1360f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".sf", 8) 1361f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ngle", 9) 1362f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".seq", 10) 1363f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ngl", 11) 1364f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".lt", 12) 1365f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".nge", 13) 1366f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".le", 14) 1367f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".ngt", 15) 1368f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(-1); 1369f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1370f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return CC; 1371f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 1372f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1373f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser:: 1374f740d6e328bd10904b079e1ce6583f436d6c9817Jack CarterparseMathOperation(StringRef Name, SMLoc NameLoc, 137530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 137630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // split the format 1377f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Start = Name.find('.'), Next = Name.rfind('.'); 1378f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format1 = Name.slice(Start, Next); 137930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // and add the first format to the operands 1380f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 138130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // now for the second format 1382f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format2 = Name.slice(Next, StringRef::npos); 1383f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1384f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 138530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // set the format for the first register 1386f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format1); 1387f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1388f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Read the remaining operands. 1389f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1390f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Read the first operand. 1391f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (ParseOperand(Operands, Name)) { 1392f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1393cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1394f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1395f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1396f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1397f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::Comma)) { 1398f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1399cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1400f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1401f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1402f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1403f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.Lex(); // Eat the comma. 1404f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1405f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter //set the format for the first register 1406f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format2); 1407f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1408f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Parse and remember the operand. 1409f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (ParseOperand(Operands, Name)) { 1410f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1411cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1412f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1413f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1414f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1415f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1416f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1417f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1418cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1419f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1420f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1421f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1422f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Parser.Lex(); // Consume the EndOfStatement 1423f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return false; 1424f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 1425f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1426fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 14276a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1428fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 142999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter StringRef Mnemonic; 143030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // floating point instructions: should register be treated as double? 1431f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (requestsDoubleOperand(Name)) { 1432f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(FP_FORMAT_D); 1433ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 143499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter Mnemonic = Name; 1435f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1436f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else { 1437f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setDefaultFpFormat(); 1438f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Create the leading tokens for the mnemonic, split by '.' characters. 1439f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Start = 0, Next = Name.find('.'); 144099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter Mnemonic = Name.slice(Start, Next); 1441f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1442f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1443f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1444f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Next != StringRef::npos) { 144530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // there is a format token in mnemonic 144630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // StringRef Rest = Name.slice(Next, StringRef::npos); 1447f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Dot = Name.find('.', Next+1); 1448f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format = Name.slice(Next, Dot); 1449f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Dot == StringRef::npos) //only one '.' in a string, it's a format 1450f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1451f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else { 1452f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Name.startswith("c.")){ 1453f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // floating point compare, add '.' and immediate represent for cc 1454f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1455f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter int Cc = ConvertCcString(Format); 1456f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Cc == -1) { 1457f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(NameLoc, "Invalid conditional code"); 1458f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1459ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer( 1460ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.getTok().getLoc().getPointer() -1 ); 1461f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateImm( 1462f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 1463f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } else { 146430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // trunc, ceil, floor ... 1465f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return parseMathOperation(Name, NameLoc, Operands); 1466f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1467f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 146830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // the rest is a format 1469f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Format = Name.slice(Dot, StringRef::npos); 1470f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1471f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1472f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1473f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format); 1474f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1475f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1476ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1477ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the remaining operands. 1478ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1479ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the first operand. 148099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (ParseOperand(Operands, Mnemonic)) { 1481ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1482cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1483ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1484ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1485ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1486ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter while (getLexer().is(AsmToken::Comma) ) { 1487ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat the comma. 1488ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1489ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Parse and remember the operand. 1490ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ParseOperand(Operands, Name)) { 1491ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1492cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1493ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1494ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1495ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1496ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1497ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1498ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1499ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1500cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1501ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1502ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1503ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1504ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Consume the EndOfStatement 1505ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 1506fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1507fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 150830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 150930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter SMLoc Loc = getLexer().getLoc(); 1510cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 151130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return Error(Loc, ErrorMsg); 151230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 151330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 151430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() { 1515c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // Line should look like: 151630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // .set noat 151730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // set at reg to 0 151810d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(0); 151930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // eat noat 152030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 1521c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // If this is not the end of the statement, report error 152230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 152330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 152430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 152530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 152630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // Consume the EndOfStatement 152730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 152830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 152930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() { 153030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // line can be 153130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // .set at - defaults to $1 153230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // or .set at=$reg 153399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int AtRegNo; 153430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter getParser().Lex(); 153530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().is(AsmToken::EndOfStatement)) { 153610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(1); 153730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // Consume the EndOfStatement 153830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 153930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (getLexer().is(AsmToken::Equal)) { 1540c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter getParser().Lex(); // eat '=' 154130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::Dollar)) { 154230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 154330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 154430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 1545c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.Lex(); // Eat '$' 154699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter const AsmToken &Reg = Parser.getTok(); 154799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (Reg.is(AsmToken::Identifier)) { 154899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 154999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else if (Reg.is(AsmToken::Integer)) { 155099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = Reg.getIntVal(); 155199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else { 155230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 155330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 155430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 155599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 155699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if ( AtRegNo < 1 || AtRegNo > 31) { 155799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter reportParseError("unexpected token in statement"); 155899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return false; 155999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } 156099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 156199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (!Options.setATReg(AtRegNo)) { 156230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 156330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 156430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 1565c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter getParser().Lex(); // Eat reg 156630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 156730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 156830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 156930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 157030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 157130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // Consume the EndOfStatement 157230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 157330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else { 157430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 157530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 157630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 157730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 157830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 157930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() { 158030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 1581c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // If this is not the end of the statement, report error 158230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 158330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 158430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 158530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 158610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setReorder(); 158730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // Consume the EndOfStatement 158830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 158930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 159030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 159130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() { 159230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 159330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // if this is not the end of the statement, report error 159430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 159530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 159630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 159730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 159810d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setNoreorder(); 159930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // Consume the EndOfStatement 160030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 160130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 160230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 160330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() { 160430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 160530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // if this is not the end of the statement, report error 160630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 160730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 160830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 160930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 161010d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setMacro(); 161130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // Consume the EndOfStatement 161230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 161330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 161430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 161530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() { 161630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 161730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // if this is not the end of the statement, report error 161830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 161930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 162030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 162130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 162210d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter if (Options.isReorder()) { 162330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 162430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 162530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 162610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setNomacro(); 162730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); // Consume the EndOfStatement 162830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 162930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 1630c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1631c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() { 1632c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter StringRef Name; 1633c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCExpr *Value; 1634c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1635c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Parser.parseIdentifier(Name)) 1636c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter reportParseError("expected identifier after .set"); 1637c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1638c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().isNot(AsmToken::Comma)) 1639c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("unexpected token in .set directive"); 1640c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Lex(); //eat comma 1641c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1642c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Parser.parseExpression(Value)) 1643c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter reportParseError("expected valid expression after comma"); 1644c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1645c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // check if the Name already exists as a symbol 1646c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MCSymbol *Sym = getContext().LookupSymbol(Name); 1647c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Sym) { 1648c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("symbol already defined"); 1649c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1650c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym = getContext().GetOrCreateSymbol(Name); 1651c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym->setVariableValue(Value); 1652c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1653c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1654c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter} 165530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() { 165630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 165730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // get next token 165830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter const AsmToken &Tok = Parser.getTok(); 165930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 166030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Tok.getString() == "noat") { 166130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoAtDirective(); 166230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "at") { 166330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetAtDirective(); 166430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "reorder") { 166530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetReorderDirective(); 166630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "noreorder") { 166730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoReorderDirective(); 166830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "macro") { 166930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetMacroDirective(); 167030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomacro") { 167130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoMacroDirective(); 167230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomips16") { 167330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1674cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 167530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 167630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomicromips") { 167730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1678cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 167930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 1680c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } else { 1681c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // it is just an identifier, look for assignment 1682c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter parseSetAssignment(); 1683c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 168430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 1685801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 168630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 168730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 168830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1689801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// parseDirectiveWord 1690801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// ::= .word [ expression (, expression)* ] 1691801c5838830d190a6b0d8e462bd43805f66ba50fJack Carterbool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1692801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1693801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter for (;;) { 1694801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter const MCExpr *Value; 1695cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Value)) 1696801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return true; 1697801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1698801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter getParser().getStreamer().EmitValue(Value, Size); 1699801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1700801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().is(AsmToken::EndOfStatement)) 1701801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter break; 1702801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1703801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter // FIXME: Improve diagnostic. 1704801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::Comma)) 1705801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return Error(L, "unexpected token in directive"); 1706801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 1707801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1708801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1709801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1710801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 1711801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 1712801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter} 1713801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 171430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1715acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1716801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter StringRef IDVal = DirectiveID.getString(); 1717801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1718801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if ( IDVal == ".ent") { 171930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1720acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 1721acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1722acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1723acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1724801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".end") { 172530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1726acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 1727acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1728acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1729acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1730801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".frame") { 173130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1732cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1733acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1734acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1735acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1736801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".set") { 173730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseDirectiveSet(); 1738acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1739acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1740801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".fmask") { 174130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1742cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1743acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1744acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1745acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1746801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".mask") { 174730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1748cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1749acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1750acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1751acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1752801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".gpword") { 175330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // ignore this directive for now 1754cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1755acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1756acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1757acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1758801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".word") { 1759801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter parseDirectiveWord(4, DirectiveID.getLoc()); 1760801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 1761801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1762801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1763fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 1764fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1765fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 1766fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() { 1767fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1768fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1769fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1770fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1771fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1772ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1773ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER 1774ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION 1775ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc" 1776