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 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/MipsMCExpr.h" 11fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h" 12ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h" 13320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "MipsTargetStreamer.h" 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/APInt.h" 15ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/ADT/StringSwitch.h" 16ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h" 17ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h" 18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCInstBuilder.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 22ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h" 23ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h" 24ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h" 2572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCTargetAsmParser.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Debug.h" 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MathExtras.h" 28ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/Support/TargetRegistry.h" 29fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 30fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm; 31fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mips-asm-parser" 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 34715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Goulynamespace llvm { 35715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Goulyclass MCInstrInfo; 36715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly} 37715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly 38fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace { 3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions { 4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic: 412263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {} 4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 432263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic unsigned getATRegNum() { return aTReg; } 4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool setATReg(unsigned Reg); 45ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 462263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic bool isReorder() { return reorder; } 472263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic void setReorder() { reorder = true; } 482263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic void setNoreorder() { reorder = false; } 4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 502263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic bool isMacro() { return macro; } 512263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic void setMacro() { macro = true; } 522263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic void setNomacro() { macro = false; } 5330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 5430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate: 5530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter unsigned aTReg; 5630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool reorder; 5730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool macro; 5830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}; 5930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 6030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 6130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace { 62fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser { 63320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola MipsTargetStreamer &getTargetStreamer() { 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer(); 65320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola return static_cast<MipsTargetStreamer &>(TS); 66320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola } 67320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 68ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCSubtargetInfo &STI; 69ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &Parser; 7010d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter MipsAssemblerOptions Options; 7130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 7272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER 7372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc" 7472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned checkTargetMatchPredicate(MCInst &Inst) override; 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 7784125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OperandVector &Operands, MCStreamer &Out, 79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned &ErrorInfo, 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool MatchingInlineAsm) override; 81fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Parse a register as used in CFI directives 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 84fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool ParseParenSuffix(StringRef Name, OperandVector &Operands); 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool ParseBracketSuffix(StringRef Name, OperandVector &Operands); 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 90cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc NameLoc, OperandVector &Operands) override; 91fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool ParseDirective(AsmToken DirectiveID) override; 93fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands); 9542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 9642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter MipsAsmParser::OperandMatchResultTy 97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MatchAnyRegisterNameWithoutDollar(OperandVector &Operands, 98cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Identifier, SMLoc S); 9942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 10042d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter MipsAsmParser::OperandMatchResultTy 101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S); 10242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands); 10442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands); 106006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida 107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands); 108d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic 109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands); 11095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands); 112c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool searchSymbolAlias(OperandVector &Operands); 114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool ParseOperand(OperandVector &, StringRef Mnemonic); 116ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1179d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter bool needsExpansion(MCInst &Inst); 1189d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Expands assembly pseudo instructions. 120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Returns false on success, true otherwise. 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool expandInstruction(MCInst &Inst, SMLoc IDLoc, 1222490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, 1252490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1282f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 13325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter void expandMemInst(MCInst &Inst, SMLoc IDLoc, 1342263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SmallVectorImpl<MCInst> &Instructions, bool isLoad, 1352263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic bool isImmOpnd); 136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool reportParseError(Twine ErrorMsg); 137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool reportParseError(SMLoc Loc, Twine ErrorMsg); 13830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 140ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool parseRelocOperand(const MCExpr *&Res); 14130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1422263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 1438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 1448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool isEvaluated(const MCExpr *Expr); 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool parseSetFeature(uint64_t Feature); 146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool parseDirectiveCPLoad(SMLoc Loc); 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool parseDirectiveCPSetup(); 148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool parseDirectiveNaN(); 14930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseDirectiveSet(); 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool parseDirectiveOption(); 15130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 15230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetAtDirective(); 15330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoAtDirective(); 15430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetMacroDirective(); 15530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoMacroDirective(); 15630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetReorderDirective(); 15730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoReorderDirective(); 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool parseSetNoMips16Directive(); 159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool parseSetFpDirective(); 16030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 161c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter bool parseSetAssignment(); 162c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool parseDataDirective(unsigned Size, SMLoc L); 1642263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic bool parseDirectiveGpWord(); 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool parseDirectiveGpDWord(); 166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool parseDirectiveModule(); 167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool parseDirectiveModuleFP(); 168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Directive); 170801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool eatComma(StringRef ErrorStr); 174ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 17599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int matchCPURegisterName(StringRef Symbol); 17699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 177ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 178ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 179bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic int matchFPURegisterName(StringRef Name); 1807231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 181bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic int matchFCCRegisterName(StringRef Name); 182f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 183bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic int matchACRegisterName(StringRef Name); 184f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 18542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter int matchMSA128RegisterName(StringRef Name); 18642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 187006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida int matchMSA128CtrlRegisterName(StringRef Name); 188006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida 18986924b4182537745659f2660244f3402c1e1ca4dJack Carter unsigned getReg(int RC, int RegNo); 190038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getGPR(int RegNo); 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int getATReg(SMLoc Loc); 19425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 19525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool processInstruction(MCInst &Inst, SMLoc IDLoc, 1962263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SmallVectorImpl<MCInst> &Instructions); 19745ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida 19845ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida // Helper function that checks if the value of a vector index is within the 19945ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida // boundaries of accepted values for each RegisterKind 20045ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 20145ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida bool validateMSAIndex(int Val, int RegKind); 20245ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void setFeatureBits(unsigned Feature, StringRef FeatureString) { 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!(STI.getFeatureBits() & Feature)) { 205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines setAvailableFeatures( 206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void clearFeatureBits(unsigned Feature, StringRef FeatureString) { 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (STI.getFeatureBits() & Feature) { 212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines setAvailableFeatures( 213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 217fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic: 218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines enum MipsMatchResultTy { 219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY 220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#define GET_OPERAND_DIAGNOSTIC_TYPES 221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "MipsGenAsmMatcher.inc" 222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#undef GET_OPERAND_DIAGNOSTIC_TYPES 223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines }; 225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 226715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCInstrInfo &MII, const MCTargetOptions &Options) 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : MCTargetAsmParser(), STI(sti), Parser(parser) { 229ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Initialize the set of available features. 230ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().updateABIInfo(*this); 233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Assert exactly one ABI was chosen. 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); 239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isABI_O32() && !allowOddSPReg() != 0) 241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines report_fatal_error("-mno-odd-spreg requires the O32 ABI"); 242fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola } 243fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 244ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &getParser() const { return Parser; } 245ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmLexer &getLexer() const { return Parser.getLexer(); } 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 247cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// True if all of $fcc0 - $fcc7 exist for the current ISA. 248cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); } 249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } 251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; } 252cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; } 253cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 254cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; } 255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isABI_FPXX() const { return false; } // TODO: add check for FeatureXX 256cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 257cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool allowOddSPReg() const { 258cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg); 259cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 260cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool inMicroMipsMode() const { 262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return STI.getFeatureBits() & Mips::FeatureMicroMips; 263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; } 265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; } 266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } 267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; } 268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; } 269cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips32() const { 270cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (STI.getFeatureBits() & Mips::FeatureMips32); 271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 272cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips64() const { 273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (STI.getFeatureBits() & Mips::FeatureMips64); 274cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 275cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips32r2() const { 276cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (STI.getFeatureBits() & Mips::FeatureMips32r2); 277cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 278cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips64r2() const { 279cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (STI.getFeatureBits() & Mips::FeatureMips64r2); 280cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips32r6() const { 282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (STI.getFeatureBits() & Mips::FeatureMips32r6); 283cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 284cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMips64r6() const { 285cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return (STI.getFeatureBits() & Mips::FeatureMips64r6); 286cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); } 288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); } 289cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); } 290cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool inMips16Mode() const { 292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return STI.getFeatureBits() & Mips::FeatureMips16; 293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // TODO: see how can we get this info. 295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool mipsSEUsesSoftFloat() const { return false; } 296cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Warn if RegNo is the current assembler temporary. 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc); 299fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}; 300fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 301fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 30272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace { 30372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 30472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine 30572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction. 30672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand { 307ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic: 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Broad categories of register classes 30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// The exact class is finalized by the render method. 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines enum RegKind { 311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit()) 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 313cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines /// isFP64bit()) 31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_FCC = 4, /// FCC 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_MSACtrl = 16, /// MSA control registers 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_COP2 = 32, /// COP2 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// context). 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_CCR = 128, /// CCR 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_HWRegs = 256, /// HWRegs 322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RegKind_COP3 = 512, /// COP3 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Potentially any (e.g. $1) 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RegKind_CCR | RegKind_HWRegs | RegKind_COP3 328ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter }; 329ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 330ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate: 33172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka enum KindTy { 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines k_Immediate, /// An immediate (possibly involving symbol references) 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines k_Memory, /// Base + Offset Memory Address 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines k_PhysRegister, /// A physical register from the Mips namespace 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines k_RegisterIndex, /// A register index in one or more RegKind. 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines k_Token /// A simple token 33772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } Kind; 33872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 339cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic: 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand(KindTy K, MipsAsmParser &Parser) 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 343cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprivate: 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// For diagnostics, and checking the assembler temporary 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsAsmParser &AsmParser; 346ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 347a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token { 348a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const char *Data; 349a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Length; 350a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 351a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct PhysRegOp { 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Num; /// Register Number 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct RegIdxOp { 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Index; /// Index into the register class 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegKind Kind; /// Bitfield of the kinds it could possibly be 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCRegisterInfo *RegInfo; 360a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 361a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 362a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp { 363a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Val; 364a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 365a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 366a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp { 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand *Base; 368a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Off; 369a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 370a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 371ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter union { 372a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token Tok; 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct PhysRegOp PhysReg; 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct RegIdxOp RegIdx; 375a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp Imm; 376a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp Mem; 377ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter }; 378ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 379ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc StartLoc, EndLoc; 380ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Internal constructor for register kinds 382cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind, 383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCRegisterInfo *RegInfo, 384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc S, SMLoc E, 385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser &Parser) { 386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser); 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Op->RegIdx.Index = Index; 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Op->RegIdx.RegInfo = RegInfo; 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Op->RegIdx.Kind = RegKind; 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Op->StartLoc = S; 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Op->EndLoc = E; 39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Op; 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 39572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic: 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to GPR32 and return the real register for the current 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getGPR32Reg() const { 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc); 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::GPR32RegClassID; 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 40372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 404ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to GPR64 and return the real register for the current 40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getGPR64Reg() const { 40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::GPR64RegClassID; 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate: 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to AFGR64 and return the real register for the current 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getAFGR64Reg() const { 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (RegIdx.Index % 2 != 0) 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsmParser.Warning(StartLoc, "Float register should be even."); 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .getRegister(RegIdx.Index / 2); 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to FGR64 and return the real register for the current 42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getFGR64Reg() const { 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .getRegister(RegIdx.Index); 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to FGR32 and return the real register for the current 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getFGR32Reg() const { 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .getRegister(RegIdx.Index); 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to FGRH32 and return the real register for the current 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getFGRH32Reg() const { 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .getRegister(RegIdx.Index); 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to FCC and return the real register for the current 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getFCCReg() const { 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .getRegister(RegIdx.Index); 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to MSA128 and return the real register for the current 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// target. 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getMSA128Reg() const { 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // identical 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::MSA128BRegClassID; 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to MSACtrl and return the real register for the 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// current target. 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getMSACtrlReg() const { 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::MSACtrlRegClassID; 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to COP2 and return the real register for the 47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// current target. 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getCOP2Reg() const { 47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::COP2RegClassID; 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// Coerce the register to COP3 and return the real register for the 483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// current target. 484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned getCOP3Reg() const { 485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); 486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned ClassID = Mips::COP3RegClassID; 487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to ACC64DSP and return the real register for the 49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// current target. 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getACC64DSPReg() const { 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::ACC64DSPRegClassID; 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to HI32DSP and return the real register for the 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// current target. 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getHI32DSPReg() const { 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::HI32DSPRegClassID; 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to LO32DSP and return the real register for the 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// current target. 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getLO32DSPReg() const { 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::LO32DSPRegClassID; 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to CCR and return the real register for the 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// current target. 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getCCRReg() const { 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::CCRRegClassID; 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Coerce the register to HWRegs and return the real register for the 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// current target. 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getHWRegsReg() const { 52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned ClassID = Mips::HWRegsRegClassID; 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 528a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka } 529a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka 53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 5312263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic void addExpr(MCInst &Inst, const MCExpr *Expr) const { 532ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Add as immediate when possible. Null MCExpr = 0. 533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Expr) 534ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(0)); 535ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 536ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 537ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else 538ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateExpr(Expr)); 53972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 540ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addRegOperands(MCInst &Inst, unsigned N) const { 54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Use a custom parser instead"); 54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Render the operand to an MCInst as a GPR32 54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Asserts if the wrong number of operands are requested, or the operand 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// is not a k_RegisterIndex compatible with RegKind_GPR 54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); 55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Render the operand to an MCInst as a GPR64 55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Asserts if the wrong number of operands are requested, or the operand 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// is not a k_RegisterIndex compatible with RegKind_GPR 55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); 574cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // FIXME: We ought to do this for -integrated-as without -via-file-asm too. 575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!AsmParser.allowOddSPReg() && RegIdx.Index & 1) 576cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU " 577cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "registers"); 57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); 58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getFCCReg())); 58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); 59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); 59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); 60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { 606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(N == 1 && "Invalid number of operands!"); 607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Inst.addOperand(MCOperand::CreateReg(getCOP3Reg())); 608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); 61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); 61836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); 62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getCCRReg())); 62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(N == 1 && "Invalid number of operands!"); 63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); 63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 63572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addImmOperands(MCInst &Inst, unsigned N) const { 636ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 637ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *Expr = getImm(); 63886924b4182537745659f2660244f3402c1e1ca4dJack Carter addExpr(Inst, Expr); 63972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 640ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 64172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addMemOperands(MCInst &Inst, unsigned N) const { 6426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert(N == 2 && "Invalid number of operands!"); 6436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); 6456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 6466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Expr = getMemOff(); 64786924b4182537745659f2660244f3402c1e1ca4dJack Carter addExpr(Inst, Expr); 64872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 64972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isReg() const override { 65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // As a special case until we sort out the definition of div/divu, pretend 65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isGPRAsmReg() && RegIdx.Index == 0) 65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Kind == k_PhysRegister; 65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isRegIdx() const { return Kind == k_RegisterIndex; } 659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isImm() const override { return Kind == k_Immediate; } 66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isConstantImm() const { 66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isImm() && dyn_cast<MCConstantExpr>(getImm()); 66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isToken() const override { 66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Note: It's not possible to pretend that other operand kinds are tokens. 66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The matcher emitter checks tokens first. 66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Kind == k_Token; 66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isMem() const override { return Kind == k_Memory; } 669cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool isConstantMemOff() const { 670cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return isMem() && dyn_cast<MCConstantExpr>(getMemOff()); 671cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 672cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines template <unsigned Bits> bool isMemWithSimmOffset() const { 673cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()); 674cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 675d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic bool isInvNum() const { return Kind == k_Immediate; } 67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isLSAImm() const { 67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!isConstantImm()) 67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t Val = getConstantImm(); 68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 1 <= Val && Val <= 4; 68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 68272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 68372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka StringRef getToken() const { 68472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert(Kind == k_Token && "Invalid access!"); 685ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return StringRef(Tok.Data, Tok.Length); 68672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 68772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned getReg() const override { 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // As a special case until we sort out the definition of div/divu, pretend 69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegIdx.Kind & RegKind_GPR) 69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getGPR32Reg(); // FIXME: GPR64 too 694a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka 69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Kind == k_PhysRegister && "Invalid access!"); 69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return PhysReg.Num; 697ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 698ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 699ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *getImm() const { 70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((Kind == k_Immediate) && "Invalid access!"); 701ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Imm.Val; 702ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 703ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t getConstantImm() const { 70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *Val = getImm(); 70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return static_cast<const MCConstantExpr *>(Val)->getValue(); 70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand *getMemBase() const { 7106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 7116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Base; 7126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 7136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 7146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *getMemOff() const { 7156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 7166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Off; 7176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 7186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 719cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int64_t getConstantMemOff() const { 720cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return static_cast<const MCConstantExpr *>(getMemOff())->getValue(); 721cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 722cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 723cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, 724cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser &Parser) { 725cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto Op = make_unique<MipsOperand>(k_Token, Parser); 726ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Data = Str.data(); 727ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Length = Str.size(); 728ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 729ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = S; 730ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 731ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 732ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Create a numeric register (e.g. $1). The exact register remains 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// unresolved until an instruction successfully matches 735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 737cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc E, MipsAsmParser &Parser) { 73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n"); 73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 740ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 741ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Create a register that is definitely a GPR. 74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// This is typically only used for named registers such as $gp. 744cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 745cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 746cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser &Parser) { 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 748a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka } 749a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Create a register that is definitely a FGR. 75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// This is typically only used for named registers such as $f0. 752cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 753cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 754cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser &Parser) { 75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 75636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 75836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Create a register that is definitely an FCC. 75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// This is typically only used for named registers such as $fcc0. 760cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 761cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 762cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser &Parser) { 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Create a register that is definitely an ACC. 76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// This is typically only used for named registers such as $ac0. 768cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 769cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 770cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsAsmParser &Parser) { 77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Create a register that is definitely an MSA128. 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// This is typically only used for named registers such as $w0. 776cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 777cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 778cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc E, MipsAsmParser &Parser) { 77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Create a register that is definitely an MSACtrl. 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// This is typically only used for named registers such as $msaaccess. 784cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 785cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 786cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc E, MipsAsmParser &Parser) { 78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 78872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 78972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 790cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 791cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { 792cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto Op = make_unique<MipsOperand>(k_Immediate, Parser); 79395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida Op->Imm.Val = Val; 79495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida Op->StartLoc = S; 79595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida Op->EndLoc = E; 79695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida return Op; 79795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida } 79895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static std::unique_ptr<MipsOperand> 800cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S, 801cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc E, MipsAsmParser &Parser) { 802cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto Op = make_unique<MipsOperand>(k_Memory, Parser); 803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Op->Mem.Base = Base.release(); 8046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Off = Off; 8056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->StartLoc = S; 8066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->EndLoc = E; 8076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Op; 8086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 8096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isGPRAsmReg() const { 81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 81290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic } 81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isFGRAsmReg() const { 81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // AFGR64 is $0-$15 but we handle this in getAFGR64() 81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 816a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka } 81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isHWRegsAsmReg() const { 81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 81988373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka } 82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isCCRAsmReg() const { 82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 82288373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka } 82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isFCCAsmReg() const { 824cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) 825cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 826cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!AsmParser.hasEightFccRegisters()) 827cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return RegIdx.Index == 0; 828cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return RegIdx.Index <= 7; 82942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter } 83036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isACCAsmReg() const { 83136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 83242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter } 83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isCOP2AsmReg() const { 83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 83542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter } 836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isCOP3AsmReg() const { 837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; 838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isMSA128AsmReg() const { 84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 84142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter } 84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isMSACtrlAsmReg() const { 84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 844006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida } 845006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida 846ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getStartLoc - Get the location of the first token of this operand. 847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SMLoc getStartLoc() const override { return StartLoc; } 848ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getEndLoc - Get the location of the last token of this operand. 849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SMLoc getEndLoc() const override { return EndLoc; } 850ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines virtual ~MipsOperand() { 852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (Kind) { 853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case k_Immediate: 854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case k_Memory: 856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines delete Mem.Base; 857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case k_PhysRegister: 859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case k_RegisterIndex: 860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case k_Token: 861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void print(raw_ostream &OS) const override { 86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Kind) { 86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case k_Immediate: 86836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "Imm<"; 86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Imm.Val->print(OS); 87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << ">"; 87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case k_Memory: 87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "Mem<"; 87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mem.Base->print(OS); 87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << ", "; 87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Mem.Off->print(OS); 87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << ">"; 87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case k_PhysRegister: 88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "PhysReg<" << PhysReg.Num << ">"; 88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case k_RegisterIndex: 88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 88436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case k_Token: 88636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << Tok.Data; 88736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 88972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 89086924b4182537745659f2660244f3402c1e1ca4dJack Carter}; // class MipsOperand 8912263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic} // namespace 89272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 89325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm { 89425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[]; 89525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 89625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 89725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return MipsInsts[Opcode]; 89825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 89925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 90025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 9018afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter SmallVectorImpl<MCInst> &Instructions) { 90225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 90425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Inst.setLoc(IDLoc); 90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MCID.isBranch() || MCID.isCall()) { 90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const unsigned Opcode = Inst.getOpcode(); 90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOperand Offset; 90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Opcode) { 91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 91236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 91336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BEQ: 91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BNE: 91536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BEQ_MM: 91636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BNE_MM: 91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset = Inst.getOperand(2); 91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Offset.isImm()) 92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; // We'll deal with this situation later on when applying fixups. 921cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(IDLoc, "branch target out of range"); 923cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OffsetToAlignment(Offset.getImm(), 924cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1LL << (inMicroMipsMode() ? 1 : 2))) 92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(IDLoc, "branch to misaligned address"); 92636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BGEZ: 92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BGTZ: 92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BLEZ: 93036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BLTZ: 93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BGEZAL: 93236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BLTZAL: 93336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BC1F: 93436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BC1T: 93536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BGEZ_MM: 93636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BGTZ_MM: 93736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BLEZ_MM: 93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BLTZ_MM: 93936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BGEZAL_MM: 94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BLTZAL_MM: 94136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BC1F_MM: 94236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case Mips::BC1T_MM: 94336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 94436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset = Inst.getOperand(1); 94536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Offset.isImm()) 94636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; // We'll deal with this situation later on when applying fixups. 947cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 94836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(IDLoc, "branch target out of range"); 949cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (OffsetToAlignment(Offset.getImm(), 950cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1LL << (inMicroMipsMode() ? 1 : 2))) 95136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(IDLoc, "branch to misaligned address"); 95236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 95336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 95436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 95536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 956cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // SSNOP is deprecated on MIPS32r6/MIPS64r6 957cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We still accept it but it is a normal nop. 958cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) { 959cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6"; 960cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a " 961cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "nop instruction"); 962cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 963cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 96497265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter if (MCID.hasDelaySlot() && Options.isReorder()) { 96597265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter // If this instruction has a delay slot and .set reorder is active, 96697265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter // emit a NOP after it. 96797265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter Instructions.push_back(Inst); 96897265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter MCInst NopInst; 96997265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.setOpcode(Mips::SLL); 97097265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 97197265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 97297265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.addOperand(MCOperand::CreateImm(0)); 97397265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter Instructions.push_back(NopInst); 97497265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter return false; 97597265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter } 97697265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter 97725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MCID.mayLoad() || MCID.mayStore()) { 97825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Check the offset of memory operand, if it is a symbol 97986924b4182537745659f2660244f3402c1e1ca4dJack Carter // reference or immediate we may have to expand instructions. 98086924b4182537745659f2660244f3402c1e1ca4dJack Carter for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 98125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 9822263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 9832263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 98425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCOperand &Op = Inst.getOperand(i); 98525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (Op.isImm()) { 98625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter int MemOffset = Op.getImm(); 98725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MemOffset < -32768 || MemOffset > 32767) { 98886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Offset can't exceed 16bit value. 98986924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 99025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 99125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 99225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } else if (Op.isExpr()) { 99325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *Expr = Op.getExpr(); 99486924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Expr->getKind() == MCExpr::SymbolRef) { 99525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR = 9962263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic static_cast<const MCSymbolRefExpr *>(Expr); 99725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (SR->getKind() == MCSymbolRefExpr::VK_None) { 99886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Expand symbol. 99986924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 100025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 100125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 10028afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else if (!isEvaluated(Expr)) { 100386924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 10048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 100525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 100625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 100725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 100886924b4182537745659f2660244f3402c1e1ca4dJack Carter } // for 10092263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic } // if load/store 101025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 101125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (needsExpansion(Inst)) 1012cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return expandInstruction(Inst, IDLoc, Instructions); 101325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else 101425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(Inst); 101525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 101625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 101725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 101825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 10199d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) { 10209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 102186924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (Inst.getOpcode()) { 102286924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadImm32Reg: 102386924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Imm: 102486924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Reg: 1025cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case Mips::LoadImm64Reg: 102686924b4182537745659f2660244f3402c1e1ca4dJack Carter return true; 102786924b4182537745659f2660244f3402c1e1ca4dJack Carter default: 102886924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 10299d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 10309d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 10312490dc650895149423bb59538dc03ca352222702Jack Carter 1032cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 10332263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SmallVectorImpl<MCInst> &Instructions) { 103486924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (Inst.getOpcode()) { 1035cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines default: 1036cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(0 && "unimplemented expansion"); 1037cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 103886924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadImm32Reg: 103986924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadImm(Inst, IDLoc, Instructions); 1040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case Mips::LoadImm64Reg: 1041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isGP64bit()) { 1042cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1043cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 1044cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1045cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return expandLoadImm(Inst, IDLoc, Instructions); 104686924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Imm: 104786924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadAddressImm(Inst, IDLoc, Instructions); 104886924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Reg: 104986924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadAddressReg(Inst, IDLoc, Instructions); 105086924b4182537745659f2660244f3402c1e1ca4dJack Carter } 10519d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 10522490dc650895149423bb59538dc03ca352222702Jack Carter 1053cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesnamespace { 1054cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <int Shift, bool PerformShift> 1055cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc, 1056cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SmallVectorImpl<MCInst> &Instructions) { 1057cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCInst tmpInst; 1058cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (PerformShift) { 1059cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.setOpcode(Mips::DSLL); 1060cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1061cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1062cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand(MCOperand::CreateImm(16)); 1063cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.setLoc(IDLoc); 1064cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Instructions.push_back(tmpInst); 1065cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.clear(); 1066cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1067cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.setOpcode(Mips::ORi); 1068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1069cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1070cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand( 1071cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift))); 1072cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.setLoc(IDLoc); 1073cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Instructions.push_back(tmpInst); 1074cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1075cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1077cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 107886924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 10792490dc650895149423bb59538dc03ca352222702Jack Carter MCInst tmpInst; 10809d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &ImmOp = Inst.getOperand(1); 10812f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 10829d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &RegOp = Inst.getOperand(0); 10839d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter assert(RegOp.isReg() && "expected register operand kind"); 10849d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 1085cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int64_t ImmValue = ImmOp.getImm(); 10862490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.setLoc(IDLoc); 1087cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // FIXME: gas has a special case for values that are 000...1111, which 1088cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // becomes a li -1 and then a dsrl 108986924b4182537745659f2660244f3402c1e1ca4dJack Carter if (0 <= ImmValue && ImmValue <= 65535) { 109086924b4182537745659f2660244f3402c1e1ca4dJack Carter // For 0 <= j <= 65535. 10919d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => ori d,$zero,j 1092ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 10932490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 109486924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 10952490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 10969d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 109786924b4182537745659f2660244f3402c1e1ca4dJack Carter } else if (ImmValue < 0 && ImmValue >= -32768) { 109886924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j < 0. 10999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => addiu d,$zero,j 1100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 11012490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 110286924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 11032490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 11049d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 1105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if ((ImmValue & 0xffffffff) == ImmValue) { 1106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // For any value of j that is representable as a 32-bit integer, create 1107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // a sequence of: 11089d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => lui d,hi16(j) 11092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter // ori d,d,lo16(j) 1110ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 11112490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 11122490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 11139d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 1114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if ((ImmValue & (0xffffLL << 48)) == 0) { 1116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isGP64bit()) { 1117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 1119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // <------- lo32 ------> 1122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // <------- hi32 ------> 1123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // <- hi16 -> <- lo16 -> 1124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // _________________________________ 1125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // | | | | 1126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // | 16-bytes | 16-bytes | 16-bytes | 1127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // |__________|__________|__________| 1128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 1129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // For any value of j that is representable as a 48-bit integer, create 1130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // a sequence of: 1131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // li d,j => lui d,hi16(j) 1132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ori d,d,hi16(lo32(j)) 1133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // dsll d,d,16 1134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ori d,d,lo16(lo32(j)) 1135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.setOpcode(Mips::LUi); 11362490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand( 1138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32)); 1139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Instructions.push_back(tmpInst); 1140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 1143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isGP64bit()) { 1144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 1146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // <------- hi32 ------> <------- lo32 ------> 1149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // <- hi16 -> <- lo16 -> 1150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ___________________________________________ 1151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // | | | | | 1152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // | 16-bytes | 16-bytes | 16-bytes | 16-bytes | 1153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // |__________|__________|__________|__________| 1154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 1155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // For any value of j that isn't representable as a 48-bit integer. 1156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // li d,j => lui d,hi16(j) 1157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ori d,d,lo16(hi32(j)) 1158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // dsll d,d,16 1159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ori d,d,hi16(lo32(j)) 1160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // dsll d,d,16 1161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ori d,d,lo16(lo32(j)) 1162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.setOpcode(Mips::LUi); 11632490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines tmpInst.addOperand( 1165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48)); 11669d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 1167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 11709d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 1171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 11729d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 11732490dc650895149423bb59538dc03ca352222702Jack Carter 1174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool 11752263a2ca72e21206d45a69532004a0b17881e733Vladimir MedicMipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 11762263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SmallVectorImpl<MCInst> &Instructions) { 11772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 11782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(2); 11792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 11802f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &SrcRegOp = Inst.getOperand(1); 11812f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(SrcRegOp.isReg() && "expected register operand kind"); 11822f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &DstRegOp = Inst.getOperand(0); 11832f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(DstRegOp.isReg() && "expected register operand kind"); 11842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 118586924b4182537745659f2660244f3402c1e1ca4dJack Carter if (-32768 <= ImmValue && ImmValue <= 65535) { 118686924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j <= 65535. 118786924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j(s) => addiu d,s,j 1188ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 11892f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 11902f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 11912f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 11922f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 11932f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 119486924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 119586924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j(s) => lui d,hi16(j) 119686924b4182537745659f2660244f3402c1e1ca4dJack Carter // ori d,d,lo16(j) 119786924b4182537745659f2660244f3402c1e1ca4dJack Carter // addu d,d,s 1198ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 11992f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 12002f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 12012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 12022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 1203ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 12042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 12052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 12062f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 12072f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 12082f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 12092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDu); 12102f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 12112f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 12122f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 12132f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 12142f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 1215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 12162f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 12172f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 1218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool 12192263a2ca72e21206d45a69532004a0b17881e733Vladimir MedicMipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 12202263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SmallVectorImpl<MCInst> &Instructions) { 12212f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 12222f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(1); 12232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 12242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &RegOp = Inst.getOperand(0); 12252f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(RegOp.isReg() && "expected register operand kind"); 12262f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 122786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (-32768 <= ImmValue && ImmValue <= 65535) { 122886924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j <= 65535. 122986924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j => addiu d,$zero,j 12302f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDiu); 12312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 123286924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 12332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 12342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 12352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 123686924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 123786924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j => lui d,hi16(j) 123886924b4182537745659f2660244f3402c1e1ca4dJack Carter // ori d,d,lo16(j) 1239ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 12402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 12412f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 12422f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 12432f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 1244ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 12452f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 12462f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 12472f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 12482f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 12492f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 1250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 12512f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 12522f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 125325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 12542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SmallVectorImpl<MCInst> &Instructions, 12552263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic bool isLoad, bool isImmOpnd) { 125625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR; 125725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCInst TempInst; 125886924b4182537745659f2660244f3402c1e1ca4dJack Carter unsigned ImmOffset, HiOffset, LoOffset; 125925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *ExprOffset; 126025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned TmpRegNum; 126186924b4182537745659f2660244f3402c1e1ca4dJack Carter // 1st operand is either the source or destination register. 126225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 126325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned RegOpNum = Inst.getOperand(0).getReg(); 126486924b4182537745659f2660244f3402c1e1ca4dJack Carter // 2nd operand is the base register. 126525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 126625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned BaseRegNum = Inst.getOperand(1).getReg(); 126786924b4182537745659f2660244f3402c1e1ca4dJack Carter // 3rd operand is either an immediate or expression. 126825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) { 126925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 127025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ImmOffset = Inst.getOperand(2).getImm(); 127125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter LoOffset = ImmOffset & 0x0000ffff; 127225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset = (ImmOffset & 0xffff0000) >> 16; 127386924b4182537745659f2660244f3402c1e1ca4dJack Carter // If msb of LoOffset is 1(negative number) we must increment HiOffset. 127425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (LoOffset & 0x8000) 127525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset++; 127686924b4182537745659f2660244f3402c1e1ca4dJack Carter } else 127725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ExprOffset = Inst.getOperand(2).getExpr(); 127886924b4182537745659f2660244f3402c1e1ca4dJack Carter // All instructions will have the same location. 127925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setLoc(IDLoc); 1280cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // These are some of the types of expansions we perform here: 1281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 1) lw $8, sym => lui $8, %hi(sym) 1282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // lw $8, %lo(sym)($8) 1283cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 2) lw $8, offset($9) => lui $8, %hi(offset) 1284cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // add $8, $8, $9 1285cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // lw $8, %lo(offset)($9) 1286cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 3) lw $8, offset($8) => lui $at, %hi(offset) 1287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // add $at, $at, $8 1288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // lw $8, %lo(offset)($at) 1289cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 4) sw $8, sym => lui $at, %hi(sym) 1290cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // sw $8, %lo(sym)($at) 1291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 5) sw $8, offset($8) => lui $at, %hi(offset) 1292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // add $at, $at, $8 1293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // sw $8, %lo(offset)($at) 1294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 6) ldc1 $f0, sym => lui $at, %hi(sym) 1295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // ldc1 $f0, %lo(sym)($at) 1296cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // 1297cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // For load instructions we can use the destination register as a temporary 1298cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // if base and dst are different (examples 1 and 2) and if the base register 1299cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // is general purpose otherwise we must use $at (example 6) and error if it's 1300cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // not available. For stores we must use $at (examples 4 and 5) because we 1301cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // must not clobber the source register setting up the offset. 1302cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode()); 1303cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int16_t RegClassOp0 = Desc.OpInfo[0].RegClass; 1304cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned RegClassIDOp0 = 1305cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID(); 1306cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) || 1307cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (RegClassIDOp0 == Mips::GPR64RegClassID); 1308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (isLoad && IsGPR && (BaseRegNum != RegOpNum)) 1309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpRegNum = RegOpNum; 1310cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else { 1311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int AT = getATReg(IDLoc); 1312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // At this point we need AT to perform the expansions and we exit if it is 1313cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // not available. 1314cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!AT) 1315cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return; 1316cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpRegNum = getReg( 1317cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT); 1318cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 1319cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 132025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::LUi); 132125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 132225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 132325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 132425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 132525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 13262263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 132786924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 132886924b4182537745659f2660244f3402c1e1ca4dJack Carter SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 132986924b4182537745659f2660244f3402c1e1ca4dJack Carter getContext()); 133025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 13318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else { 133286924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 13338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 133425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 133525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 133686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add the instruction to the list. 133725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 133886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Prepare TempInst for next instruction. 133925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 134086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add temp register to base. 134125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::ADDu); 134225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 134325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 134425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 134525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 134625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 134736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // And finally, create original instruction with low part 134886924b4182537745659f2660244f3402c1e1ca4dJack Carter // of offset and new base. 134925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Inst.getOpcode()); 135025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 135125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 135225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 135325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 135425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 135525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 135686924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 135786924b4182537745659f2660244f3402c1e1ca4dJack Carter SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 135886924b4182537745659f2660244f3402c1e1ca4dJack Carter getContext()); 135925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 13608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else { 136186924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 13628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 136325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 136425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 136525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 136625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 136725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 136825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 1369cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesunsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 1370cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // As described by the Mips32r2 spec, the registers Rd and Rs for 1371cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // jalr.hb must be different. 1372cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Opcode = Inst.getOpcode(); 1373cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1374cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Opcode == Mips::JALR_HB && 1375cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())) 1376cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Match_RequiresDifferentSrcAndDst; 1377cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1378cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Match_Success; 1379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 1380cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1381cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1382cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OperandVector &Operands, 1383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCStreamer &Out, 1384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned &ErrorInfo, 1385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool MatchingInlineAsm) { 1386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 1387ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCInst Inst; 138825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVector<MCInst, 8> Instructions; 13892263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic unsigned MatchResult = 13902263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 1391ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1392ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (MatchResult) { 139386924b4182537745659f2660244f3402c1e1ca4dJack Carter default: 139486924b4182537745659f2660244f3402c1e1ca4dJack Carter break; 1395ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_Success: { 139686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (processInstruction(Inst, IDLoc, Instructions)) 139725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return true; 139886924b4182537745659f2660244f3402c1e1ca4dJack Carter for (unsigned i = 0; i < Instructions.size(); i++) 139936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Out.EmitInstruction(Instructions[i], STI); 1400ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 1401ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1402ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MissingFeature: 1403ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1404ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 1405ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_InvalidOperand: { 1406ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc ErrorLoc = IDLoc; 1407ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo != ~0U) { 1408ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo >= Operands.size()) 1409ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "too few operands for instruction"); 1410ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1411cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc(); 141286924b4182537745659f2660244f3402c1e1ca4dJack Carter if (ErrorLoc == SMLoc()) 141386924b4182537745659f2660244f3402c1e1ca4dJack Carter ErrorLoc = IDLoc; 1414ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1415ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1416ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(ErrorLoc, "invalid operand for instruction"); 1417ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1418ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MnemonicFail: 1419ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "invalid instruction"); 1420cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case Match_RequiresDifferentSrcAndDst: 1421cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Error(IDLoc, "source and destination must be different"); 1422ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1423fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 1424fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1425fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 142636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { 142736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) { 142836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (RegIndex == 1) 142936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Warning(Loc, "Used $at without \".set noat\""); 143036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 143136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" + 143236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Twine(RegIndex) + "\""); 143336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 143436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 143536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 143699e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) { 14372263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic int CC; 143899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 14392263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic CC = StringSwitch<unsigned>(Name) 14402263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("zero", 0) 144136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("at", 1) 14422263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("a0", 4) 14432263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("a1", 5) 14442263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("a2", 6) 14452263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("a3", 7) 14462263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("v0", 2) 14472263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("v1", 3) 14482263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s0", 16) 14492263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s1", 17) 14502263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s2", 18) 14512263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s3", 19) 14522263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s4", 20) 14532263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s5", 21) 14542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s6", 22) 14552263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("s7", 23) 14562263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("k0", 26) 14572263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("k1", 27) 145836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("gp", 28) 14592263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("sp", 29) 14602263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("fp", 30) 146136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("s8", 30) 14622263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("ra", 31) 14632263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t0", 8) 14642263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t1", 9) 14652263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t2", 10) 14662263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t3", 11) 14672263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t4", 12) 14682263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t5", 13) 14692263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t6", 14) 14702263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t7", 15) 14712263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t8", 24) 14722263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("t9", 25) 14732263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Default(-1); 147499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 1475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (isABI_N32() || isABI_N64()) { 147636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Although SGI documentation just cuts out t0-t3 for n32/n64, 147736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 147836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 147936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (8 <= CC && CC <= 11) 148036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CC += 4; 148136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 148236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CC == -1) 148336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CC = StringSwitch<unsigned>(Name) 148436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("a4", 8) 148536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("a5", 9) 148636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("a6", 10) 148736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("a7", 11) 148836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("kt0", 26) 148936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("kt1", 27) 149036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Default(-1); 149136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1492572e1bd109518f80b54d229de10699c4603944c3David Chisnall 149399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return CC; 149499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter} 149586924b4182537745659f2660244f3402c1e1ca4dJack Carter 1496bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchFPURegisterName(StringRef Name) { 1497ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1498f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Name[0] == 'f') { 1499f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef NumString = Name.substr(1); 1500f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter unsigned IntVal; 150186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (NumString.getAsInteger(10, IntVal)) 15022263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic return -1; // This is not an integer. 1503bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (IntVal > 31) // Maximum index for fpu register. 1504f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 1505bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return IntVal; 1506bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic } 1507bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return -1; 1508bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic} 1509f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1510bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchFCCRegisterName(StringRef Name) { 1511bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic 1512bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (Name.startswith("fcc")) { 1513bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic StringRef NumString = Name.substr(3); 1514bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic unsigned IntVal; 1515bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (NumString.getAsInteger(10, IntVal)) 15162263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic return -1; // This is not an integer. 1517bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (IntVal > 7) // There are only 8 fcc registers. 1518bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return -1; 1519bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return IntVal; 1520f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1521ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 1522ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 152386924b4182537745659f2660244f3402c1e1ca4dJack Carter 1524bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchACRegisterName(StringRef Name) { 1525bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic 1526899ee589f5182a35495f068ae15b5f2b5ff4ef8aAkira Hatanaka if (Name.startswith("ac")) { 1527899ee589f5182a35495f068ae15b5f2b5ff4ef8aAkira Hatanaka StringRef NumString = Name.substr(2); 1528bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic unsigned IntVal; 1529bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (NumString.getAsInteger(10, IntVal)) 15302263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic return -1; // This is not an integer. 1531bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (IntVal > 3) // There are only 3 acc registers. 1532bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return -1; 1533bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return IntVal; 1534bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic } 1535bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return -1; 1536bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic} 15377231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 153842d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carterint MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 153942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter unsigned IntVal; 154042d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 154142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 154242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter return -1; 154342d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 154442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter if (IntVal > 31) 154542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter return -1; 154642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 154742d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter return IntVal; 154842d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter} 154942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 1550006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeidaint MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 1551006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida int CC; 1552006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida 1553006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida CC = StringSwitch<unsigned>(Name) 15542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msair", 0) 15552263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msacsr", 1) 15562263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msaaccess", 2) 15572263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msasave", 3) 15582263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msamodify", 4) 15592263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msarequest", 5) 15602263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msamap", 6) 15612263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("msaunmap", 7) 15622263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Default(-1); 1563006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida 1564006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida return CC; 1565006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida} 1566006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida 156730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) { 156830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Reg > 31) 156930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 157030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 157130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter aTReg = Reg; 157230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 157330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 157430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesint MipsAsmParser::getATReg(SMLoc Loc) { 157636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int AT = Options.getATRegNum(); 157736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (AT == 0) 1578cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError(Loc, 1579cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "Pseudo instruction requires $at, which is not available"); 158036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return AT; 158136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 158230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 158386924b4182537745659f2660244f3402c1e1ca4dJack Carterunsigned MipsAsmParser::getReg(int RC, int RegNo) { 158499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 1585ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1586ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 158736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesunsigned MipsAsmParser::getGPR(int RegNo) { 1588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 158936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegNo); 159036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 159136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1592ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 1593bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (RegNum > 159436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 1595ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 1596ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1597ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return getReg(RegClass, RegNum); 1598ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1599ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1600cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) { 160136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "ParseOperand\n"); 160236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 16039d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // Check if the current operand has a custom associated parser, if so, try to 16049d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // custom parse the operand, or fallback to the general approach. 1605ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1606ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_Success) 1607ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 1608ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // If there wasn't a custom match, try the generic matcher below. Otherwise, 1609ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // there was a match, but an error occurred, in which case, just return that 1610ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // the operand parsing failed. 1611ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_ParseFail) 1612ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 1613ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 161436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << ".. Generic Parser\n"); 161536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1616ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (getLexer().getKind()) { 1617ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter default: 1618ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1619ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 1620ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Dollar: { 162186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Parse the register. 1622ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 1623ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 162436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Almost all registers have been parsed by custom parsers. There is only 162536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // one exception to this. $zero (and it's alias $0) will reach this point 162636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // for div, divu, and similar instructions because it is not an operand 162736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // to the instruction definition but an explicit register. Special case 162836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // this situation for now. 162936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ParseAnyRegister(Operands) != MatchOperand_NoMatch) 1630ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 163136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 163286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Maybe it is a symbol reference. 1633ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Identifier; 1634cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (Parser.parseIdentifier(Identifier)) 1635ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 1636ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1637ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 163838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 163986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Otherwise create a symbol reference. 16402263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic const MCExpr *Res = 16412263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1642ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 1644ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 1645ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 16462263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic // Else drop to expression parsing. 1647ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::LParen: 1648ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Minus: 1649ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Plus: 1650ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Integer: 1651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case AsmToken::Tilde: 1652ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::String: { 165336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << ".. generic integer\n"); 165436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OperandMatchResultTy ResTy = ParseImm(Operands); 165536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ResTy != MatchOperand_Success; 1656ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 16576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Percent: { 165886924b4182537745659f2660244f3402c1e1ca4dJack Carter // It is a symbol reference or constant expression. 16596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 166086924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1661ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (parseRelocOperand(IdVal)) 16626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 16636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1664ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1665ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 166636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 16676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 166830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // case AsmToken::Percent 166930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // switch(getLexer().getKind()) 1670fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 1671fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1672fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 16732263a2ca72e21206d45a69532004a0b17881e733Vladimir Medicconst MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 16748afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter StringRef RelocStr) { 16758afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter const MCExpr *Res; 167686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check the type of the expression. 16778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 167836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // It's a constant, evaluate reloc value. 167936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int16_t Val; 168036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (getVariantKind(RelocStr)) { 168136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_Mips_ABS_LO: 168236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the 1st 16-bits. 168336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = MCE->getValue() & 0xffff; 168436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 168536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_Mips_ABS_HI: 168636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low 168736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 16 bits being negative. 168836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff; 168936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 169036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_Mips_HIGHER: 169136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the 3rd 16-bits. 169236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff; 169336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 169436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_Mips_HIGHEST: 169536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the 4th 16-bits. 169636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff; 169736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 169836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 169936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines report_fatal_error("Unsupported reloc value!"); 17008afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 170136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MCConstantExpr::Create(Val, getContext()); 17028afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 17038afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 17048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 170586924b4182537745659f2660244f3402c1e1ca4dJack Carter // It's a symbol, create a symbolic expression from the symbol. 17068afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter StringRef Symbol = MSRE->getSymbol().getName(); 17078afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 170886924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 17098afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Res; 17108afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 17118afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 17128afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 171336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 171436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 171536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Try to create target expression. 171636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MipsMCExpr::isSupportedBinaryExpr(VK, BE)) 171736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MipsMCExpr::Create(VK, Expr, getContext()); 171836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 171986924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 172086924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 17218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 17228afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Res; 17238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 17248afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 17258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 172686924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 172786924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 172886924b4182537745659f2660244f3402c1e1ca4dJack Carter return Res; 17298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 173086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Just return the original expression. 17318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Expr; 17328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter} 17338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 17348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 17358afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 17368afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter switch (Expr->getKind()) { 17378afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Constant: 17388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return true; 17398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::SymbolRef: 17408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 17418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Binary: 17428afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 17438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (!isEvaluated(BE->getLHS())) 17448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 17458afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return isEvaluated(BE->getRHS()); 17468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 17478afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Unary: 17488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 174936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCExpr::Target: 175036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 17518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 17528afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 17538afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter} 17546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 175586924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 17562263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic Parser.Lex(); // Eat the % token. 175786924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 17586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok.isNot(AsmToken::Identifier)) 17596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 17606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 176138539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer std::string Str = Tok.getIdentifier().str(); 17626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 176386924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the identifier. 176486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Now make an expression from the rest of the operand. 17656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 1766ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc EndLoc; 17676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 17686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::LParen) { 17696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter while (1) { 177086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '(' token. 17716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::Percent) { 177286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the % token. 17736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &nextTok = Parser.getTok(); 17746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (nextTok.isNot(AsmToken::Identifier)) 17756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 177638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += "(%"; 177738539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += nextTok.getIdentifier(); 177886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the identifier. 17796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() != AsmToken::LParen) 17806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 17816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 17826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter break; 17836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 178486924b4182537745659f2660244f3402c1e1ca4dJack Carter if (getParser().parseParenExpression(IdVal, EndLoc)) 17856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 17866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1787ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter while (getLexer().getKind() == AsmToken::RParen) 178886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the ')' token. 17896b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 17906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 179186924b4182537745659f2660244f3402c1e1ca4dJack Carter return true; // Parenthesis must follow the relocation operand. 17926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 179386924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = evaluateRelocExpr(IdVal, Str); 17948afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 17956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 17966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1797ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1798ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc &EndLoc) { 1799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 180036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OperandMatchResultTy ResTy = ParseAnyRegister(Operands); 180136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ResTy == MatchOperand_Success) { 180236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Operands.size() == 1); 1803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 180436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StartLoc = Operand.getStartLoc(); 180536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EndLoc = Operand.getEndLoc(); 180636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 180736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // AFAIK, we only support numeric registers and named GPR's in CFI 180836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // directives. 180936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Don't worry about eating tokens before failing. Using an unrecognised 181036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // register is a parse error. 181136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Operand.isGPRAsmReg()) { 181236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Resolve to GPR32 or GPR64 appropriately. 1813cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 181436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 181536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 181636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (RegNo == (unsigned)-1); 181736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 181836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 181936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Operands.size() == 0); 18202263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic return (RegNo == (unsigned)-1); 1821ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1822ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 18238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1824ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 18258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool Result = true; 18268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 18278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter while (getLexer().getKind() == AsmToken::LParen) 18288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 1829ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 183086924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (getLexer().getKind()) { 18316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter default: 18326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 183325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter case AsmToken::Identifier: 18348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case AsmToken::LParen: 18356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Integer: 18366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Minus: 18376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Plus: 18388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (isParenExpr) 183986924b4182537745659f2660244f3402c1e1ca4dJack Carter Result = getParser().parseParenExpression(Res, S); 18408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter else 18418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Result = (getParser().parseExpression(Res)); 184286924b4182537745659f2660244f3402c1e1ca4dJack Carter while (getLexer().getKind() == AsmToken::RParen) 18438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 184486924b4182537745659f2660244f3402c1e1ca4dJack Carter break; 1845ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter case AsmToken::Percent: 18468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Result = parseRelocOperand(Res); 18476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 18488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Result; 18496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 18506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1851cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::OperandMatchResultTy 1852cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::parseMemOperand(OperandVector &Operands) { 185336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "parseMemOperand\n"); 1854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCExpr *IdVal = nullptr; 1855ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 18568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool isParenExpr = false; 1857bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 185886924b4182537745659f2660244f3402c1e1ca4dJack Carter // First operand is the offset. 1859ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter S = Parser.getTok().getLoc(); 18606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 18618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (getLexer().getKind() == AsmToken::LParen) { 18628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 18638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter isParenExpr = true; 18648afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 18656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 18668afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (getLexer().getKind() != AsmToken::Dollar) { 186786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (parseMemOffset(IdVal, isParenExpr)) 18688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_ParseFail; 18698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 187086924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get the next token. 18718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Tok.isNot(AsmToken::LParen)) { 1872cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 1873cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Mnemonic.getToken() == "la") { 18742263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SMLoc E = 18752263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 187636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 18778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_Success; 18788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 18798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Tok.is(AsmToken::EndOfStatement)) { 18802263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SMLoc E = 18812263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 18828afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 188386924b4182537745659f2660244f3402c1e1ca4dJack Carter // Zero register assumed, add a memory operand with ZERO as its base. 1884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // "Base" will be managed by k_Memory. 1885cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(), 1886cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines S, E, *this); 1887cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Operands.push_back( 1888cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 18898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_Success; 18908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 18918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Error(Parser.getTok().getLoc(), "'(' expected"); 18928afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_ParseFail; 18932f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 18946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 189586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '(' token. 18968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 18976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 189836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res = ParseAnyRegister(Operands); 1899bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (Res != MatchOperand_Success) 1900bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic return Res; 19016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1902bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic if (Parser.getTok().isNot(AsmToken::RParen)) { 19036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "')' expected"); 19046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 19056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 19066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1907ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1908ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 190986924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the ')' token. 19106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!IdVal) 19126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter IdVal = MCConstantExpr::Create(0, getContext()); 19136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 191486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Replace the register operand with the memory operand. 1915cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<MipsOperand> op( 1916cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static_cast<MipsOperand *>(Operands.back().release())); 191786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Remove the register from the operands. 1918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // "op" will be managed by k_Memory. 19196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.pop_back(); 192086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add the memory operand. 19218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 19228afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter int64_t Imm; 19238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (IdVal->EvaluateAsAbsolute(Imm)) 19248afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter IdVal = MCConstantExpr::Create(Imm, getContext()); 19258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 19268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 19278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter getContext()); 19288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 19298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 1930cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 1931ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return MatchOperand_Success; 1932ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1933ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1934cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 1935a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka 193636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 193736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sym) { 193836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc S = Parser.getTok().getLoc(); 193936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *Expr; 194036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sym->isVariable()) 194136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Expr = Sym->getVariableValue(); 194236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 1943a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka return false; 194436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Expr->getKind() == MCExpr::SymbolRef) { 194536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 194636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const StringRef DefSymbol = Ref->getSymbol().getName(); 194736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (DefSymbol.startswith("$")) { 194836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OperandMatchResultTy ResTy = 194936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 195036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ResTy == MatchOperand_Success) { 195136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 195236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 195336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (ResTy == MatchOperand_ParseFail) 195436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Should never ParseFail"); 195536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 195636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 195736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Expr->getKind() == MCExpr::Constant) { 195836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 195936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 1960cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Operands.push_back( 1961cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this)); 196236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 196336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1964a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka } 196536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 1966a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka} 1967a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka 1968ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1969cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands, 1970cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Identifier, 1971cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc S) { 197236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int Index = matchCPURegisterName(Identifier); 197336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index != -1) { 197436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateGPRReg( 197536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1976ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1977ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 197845ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida 197936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index = matchFPURegisterName(Identifier); 198036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index != -1) { 198136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateFGRReg( 198236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 198336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_Success; 198445ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida } 198545ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida 198636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index = matchFCCRegisterName(Identifier); 198736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index != -1) { 198836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateFCCReg( 198936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 199036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_Success; 199142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter } 199242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 199336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index = matchACRegisterName(Identifier); 199436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index != -1) { 199536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateACCReg( 199636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 199745ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida return MatchOperand_Success; 199836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 199945ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida 200036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index = matchMSA128RegisterName(Identifier); 200136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index != -1) { 200236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateMSA128Reg( 200336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 200445ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida return MatchOperand_Success; 200545ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida } 200645ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida 200736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index = matchMSA128CtrlRegisterName(Identifier); 200836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Index != -1) { 200936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateMSACtrlReg( 201036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 201136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_Success; 201245ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida } 201345ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida 201436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_NoMatch; 20157231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic} 20167231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 20177231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::OperandMatchResultTy 2018cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 201936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto Token = Parser.getLexer().peekTok(false); 202036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 202136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Token.is(AsmToken::Identifier)) { 202236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << ".. identifier\n"); 202336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Identifier = Token.getIdentifier(); 202436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OperandMatchResultTy ResTy = 202536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 202636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ResTy; 202736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Token.is(AsmToken::Integer)) { 202836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << ".. integer\n"); 202936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateNumericReg( 203036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 203136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *this)); 203236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_Success; 203336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 203490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 203536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 203690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 203736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_NoMatch; 203890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic} 203990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 2040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::OperandMatchResultTy 2041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseAnyRegister(OperandVector &Operands) { 204236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "ParseAnyRegister\n"); 204388373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka 204436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto Token = Parser.getTok(); 204588373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka 204636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc S = Token.getLoc(); 204788373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka 204836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Token.isNot(AsmToken::Dollar)) { 204936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 205036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Token.is(AsmToken::Identifier)) { 205136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (searchSymbolAlias(Operands)) 205236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_Success; 205336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 205436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 205588373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka return MatchOperand_NoMatch; 205636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 205736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << ".. $\n"); 205888373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka 205936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S); 206036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ResTy == MatchOperand_Success) { 206136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); // $ 206236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); // identifier 206336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 206436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ResTy; 206588373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka} 206688373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka 2067e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir MedicMipsAsmParser::OperandMatchResultTy 2068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseImm(OperandVector &Operands) { 206936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (getLexer().getKind()) { 207036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 2071e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic return MatchOperand_NoMatch; 207236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AsmToken::LParen: 207336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AsmToken::Minus: 207436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AsmToken::Plus: 207536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AsmToken::Integer: 2076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines case AsmToken::Tilde: 207736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case AsmToken::String: 207836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 207936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 2080e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic 208136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *IdVal; 2082e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic SMLoc S = Parser.getTok().getLoc(); 208336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getParser().parseExpression(IdVal)) 208436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_ParseFail; 2085e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic 208636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 208736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 2088e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic return MatchOperand_Success; 2089e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic} 2090e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic 2091cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::OperandMatchResultTy 2092cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseJumpTarget(OperandVector &Operands) { 209336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "ParseJumpTarget\n"); 209442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 209536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc S = getLexer().getLoc(); 209642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter 209736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Integers and expressions are acceptable 209836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OperandMatchResultTy ResTy = ParseImm(Operands); 209936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ResTy != MatchOperand_NoMatch) 210036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ResTy; 2101006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida 210236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Registers are a valid target and have priority over symbols. 210336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ResTy = ParseAnyRegister(Operands); 210436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ResTy != MatchOperand_NoMatch) 210536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ResTy; 2106c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 210736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *Expr = nullptr; 210836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.parseExpression(Expr)) { 210936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We have no way of knowing if a symbol was consumed so we must ParseFail 211036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_ParseFail; 2111c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 211236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back( 211336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 211436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return MatchOperand_Success; 2115ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 2116ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 2117d59ad8a8013fd76177fb61c741562af3024d34cdVladimir MedicMipsAsmParser::OperandMatchResultTy 2118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::parseInvNum(OperandVector &Operands) { 2119d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic const MCExpr *IdVal; 2120d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic // If the first token is '$' we may have register operand. 2121d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic if (Parser.getTok().is(AsmToken::Dollar)) 2122d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic return MatchOperand_NoMatch; 2123d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic SMLoc S = Parser.getTok().getLoc(); 2124d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic if (getParser().parseExpression(IdVal)) 2125d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic return MatchOperand_ParseFail; 2126d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 21272263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic assert(MCE && "Unexpected MCExpr type."); 2128d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic int64_t Val = MCE->getValue(); 2129d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2130d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic Operands.push_back(MipsOperand::CreateImm( 213136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); 2132d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic return MatchOperand_Success; 2133d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic} 2134d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic 213595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus AlmeidaMipsAsmParser::OperandMatchResultTy 2136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseLSAImm(OperandVector &Operands) { 213795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida switch (getLexer().getKind()) { 213895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida default: 213995adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida return MatchOperand_NoMatch; 214095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida case AsmToken::LParen: 214195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida case AsmToken::Plus: 214295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida case AsmToken::Minus: 214395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida case AsmToken::Integer: 214495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida break; 214595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida } 214695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 214795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida const MCExpr *Expr; 214895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida SMLoc S = Parser.getTok().getLoc(); 214995adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 215095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida if (getParser().parseExpression(Expr)) 215195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida return MatchOperand_ParseFail; 215295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 215395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida int64_t Val; 215495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida if (!Expr->EvaluateAsAbsolute(Val)) { 215595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida Error(S, "expected immediate value"); 215695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida return MatchOperand_ParseFail; 215795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida } 215895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 215995adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida // The LSA instruction allows a 2-bit unsigned immediate. For this reason 216095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida // and because the CPU always adds one to the immediate field, the allowed 216195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida // range becomes 1..4. We'll only check the range here and will deal 216295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida // with the addition/subtraction when actually decoding/encoding 216395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida // the instruction. 216495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida if (Val < 1 || Val > 4) { 216595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida Error(S, "immediate not in range (1..4)"); 216695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida return MatchOperand_ParseFail; 216795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida } 216895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 216936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back( 217036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 217195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida return MatchOperand_Success; 217295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida} 217395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida 21746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 21756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 21762263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic MCSymbolRefExpr::VariantKind VK = 21772263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 21782263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 21792263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 21802263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 21812263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 21822263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 21832263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 21842263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 21852263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 21862263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 21872263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 21882263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 21892263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 21902263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 21912263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 21922263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 21932263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 21942263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 219536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16) 219636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16) 219736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16) 219836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16) 219936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER) 220036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST) 2201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16) 2202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16) 22032263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic .Default(MCSymbolRefExpr::VK_None); 22046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 2205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(VK != MCSymbolRefExpr::VK_None); 220636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return VK; 22086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 2209f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 221036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Sometimes (i.e. load/stores) the operand may be followed immediately by 221136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// either this. 221236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '(', register, ')' 221336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handle it before we iterate so we don't get tripped up by the lack of 221436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// a comma. 2215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) { 221636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().is(AsmToken::LParen)) { 221736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back( 221836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 221936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 222036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ParseOperand(Operands, Name)) { 222136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc Loc = getLexer().getLoc(); 222236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 222336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(Loc, "unexpected token in argument list"); 222436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 222536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.getTok().isNot(AsmToken::RParen)) { 222636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc Loc = getLexer().getLoc(); 222736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 222836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(Loc, "unexpected token, expected ')'"); 222936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 223036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back( 223136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 223236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 223336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 223436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 223536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 223636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 223736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Sometimes (i.e. in MSA) the operand may be followed immediately by 223836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// either one of these. 223936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '[', register, ']' 224036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '[', integer, ']' 224136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handle it before we iterate so we don't get tripped up by the lack of 224236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// a comma. 2243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseBracketSuffix(StringRef Name, 2244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OperandVector &Operands) { 224536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().is(AsmToken::LBrac)) { 224636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back( 224736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 224836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 224936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ParseOperand(Operands, Name)) { 225036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc Loc = getLexer().getLoc(); 225136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 225236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(Loc, "unexpected token in argument list"); 225336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 225436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.getTok().isNot(AsmToken::RBrac)) { 225536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc Loc = getLexer().getLoc(); 225636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 225736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(Loc, "unexpected token, expected ']'"); 225836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 225936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back( 226036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 226136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 226236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 226336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 226436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 226536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 2267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc NameLoc, OperandVector &Operands) { 226836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "ParseInstruction\n"); 2269cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We have reached first instruction, module directive after 2270cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // this is forbidden. 2271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().setCanHaveModuleDir(false); 2272fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic // Check if we have valid mnemonic 2273f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper if (!mnemonicIsValid(Name, 0)) { 2274fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic Parser.eatToEndOfStatement(); 2275fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic return Error(NameLoc, "Unknown instruction"); 2276fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic } 2277088483627720acb58c96951b7b634f67312c7272Vladimir Medic // First operand in MCInst is instruction mnemonic. 227836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 2279ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 2280ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the remaining operands. 2281ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 2282ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the first operand. 2283088483627720acb58c96951b7b634f67312c7272Vladimir Medic if (ParseOperand(Operands, Name)) { 2284ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 2285cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 2286ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 2287ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 228836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands)) 228936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 229036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // AFAIK, parenthesis suffixes are never on the first operand 2291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 229286924b4182537745659f2660244f3402c1e1ca4dJack Carter while (getLexer().is(AsmToken::Comma)) { 229386924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the comma. 2294ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Parse and remember the operand. 2295ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ParseOperand(Operands, Name)) { 2296ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 2297cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 2298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 2299ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 230036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Parse bracket and parenthesis suffixes before we iterate 230136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().is(AsmToken::LBrac)) { 230236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ParseBracketSuffix(Name, Operands)) 230336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 230436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (getLexer().is(AsmToken::LParen) && 230536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ParseParenSuffix(Name, Operands)) 230636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 2307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 2308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 2309ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 2310ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 2311cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 2312ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 2313ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 231486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 2315ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 2316fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 2317fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 2318cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::reportParseError(Twine ErrorMsg) { 231986924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc Loc = getLexer().getLoc(); 232086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.eatToEndOfStatement(); 232186924b4182537745659f2660244f3402c1e1ca4dJack Carter return Error(Loc, ErrorMsg); 232230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 232330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 2324cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) { 2325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Error(Loc, ErrorMsg); 2326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 2327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 232830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() { 232986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Line should look like: ".set noat". 233086924b4182537745659f2660244f3402c1e1ca4dJack Carter // set at reg to 0. 233110d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(0); 233230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // eat noat 233330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 233486924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 233530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 233630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 233730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 233830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 233986924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 234030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 234130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 234286924b4182537745659f2660244f3402c1e1ca4dJack Carter 234330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() { 234486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Line can be .set at - defaults to $1 234530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // or .set at=$reg 234699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int AtRegNo; 234730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter getParser().Lex(); 234830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().is(AsmToken::EndOfStatement)) { 234910d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(1); 235086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 235130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 235230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (getLexer().is(AsmToken::Equal)) { 235386924b4182537745659f2660244f3402c1e1ca4dJack Carter getParser().Lex(); // Eat the '='. 235430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::Dollar)) { 235530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 235630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 235730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 235886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$'. 235999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter const AsmToken &Reg = Parser.getTok(); 236099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (Reg.is(AsmToken::Identifier)) { 236199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 236299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else if (Reg.is(AsmToken::Integer)) { 236399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = Reg.getIntVal(); 236499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else { 236530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 236630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 236730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 236899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 236936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (AtRegNo < 0 || AtRegNo > 31) { 237099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter reportParseError("unexpected token in statement"); 237199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return false; 237299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } 237399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 237499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (!Options.setATReg(AtRegNo)) { 237530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 237630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 237730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 237886924b4182537745659f2660244f3402c1e1ca4dJack Carter getParser().Lex(); // Eat the register. 237930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 238030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 238130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 238230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 238386924b4182537745659f2660244f3402c1e1ca4dJack Carter } 238486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 238530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 238630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else { 238730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 238830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 238930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 239030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 239130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 239230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() { 239330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 239486924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 239530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 239630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 239730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 239830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 239910d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setReorder(); 240036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getTargetStreamer().emitDirectiveSetReorder(); 240186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 240230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 240330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 240430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 240530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() { 240686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); 240786924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 240886924b4182537745659f2660244f3402c1e1ca4dJack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 240986924b4182537745659f2660244f3402c1e1ca4dJack Carter reportParseError("unexpected token in statement"); 241030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 241186924b4182537745659f2660244f3402c1e1ca4dJack Carter } 241286924b4182537745659f2660244f3402c1e1ca4dJack Carter Options.setNoreorder(); 241336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getTargetStreamer().emitDirectiveSetNoReorder(); 241486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 241586924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 241630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 241730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 241830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() { 241930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 242086924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 242130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 242230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 242330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 242430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 242510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setMacro(); 242686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 242730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 242830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 242930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 243030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() { 243130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 243286924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 243330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 243430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 243530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 243630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 243710d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter if (Options.isReorder()) { 243830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 243930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 244030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 244110d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setNomacro(); 244286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 244330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 244430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 2445c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 244636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseSetNoMips16Directive() { 244736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 244836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If this is not the end of the statement, report an error. 244936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) { 245036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reportParseError("unexpected token in statement"); 245136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 245236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 245336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For now do nothing. 245436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); // Consume the EndOfStatement. 245536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 245636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 245736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2458cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseSetFpDirective() { 2459cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsABIFlagsSection::FpABIKind FpAbiVal; 2460cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Line can be: .set fp=32 2461cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // .set fp=xx 2462cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // .set fp=64 2463cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); // Eat fp token 2464cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AsmToken Tok = Parser.getTok(); 2465cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Tok.isNot(AsmToken::Equal)) { 2466cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("unexpected token in statement"); 2467cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2468cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2469cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); // Eat '=' token. 2470cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Tok = Parser.getTok(); 2471cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2472cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!parseFpABIValue(FpAbiVal, ".set")) 2473cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2474cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) { 2476cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("unexpected token in statement"); 2477cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2478cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2479cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().emitDirectiveSetFp(FpAbiVal); 2480cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); // Consume the EndOfStatement. 2481cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2482cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 2483cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2484c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() { 2485c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter StringRef Name; 2486c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCExpr *Value; 2487c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 2488c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Parser.parseIdentifier(Name)) 2489c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter reportParseError("expected identifier after .set"); 2490c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 2491c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().isNot(AsmToken::Comma)) 2492c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("unexpected token in .set directive"); 24938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Lex(); // Eat comma 2494c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 249536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.parseExpression(Value)) 2496c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter return reportParseError("expected valid expression after comma"); 2497c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 249886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check if the Name already exists as a symbol. 2499c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MCSymbol *Sym = getContext().LookupSymbol(Name); 250086924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Sym) 2501c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("symbol already defined"); 2502c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym = getContext().GetOrCreateSymbol(Name); 2503c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym->setVariableValue(Value); 2504c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 2505c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 2506c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter} 250786924b4182537745659f2660244f3402c1e1ca4dJack Carter 250836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseSetFeature(uint64_t Feature) { 250936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 251036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) 251136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return reportParseError("unexpected token in .set directive"); 251236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (Feature) { 2514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 2515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("Unimplemented feature"); 2516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Mips::FeatureDSP: 2517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines setFeatureBits(Mips::FeatureDSP, "dsp"); 2518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveSetDsp(); 251936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 2520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Mips::FeatureMicroMips: 2521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveSetMicroMips(); 252236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 2523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Mips::FeatureMips16: 2524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveSetMips16(); 252536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 2526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Mips::FeatureMips32r2: 2527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines setFeatureBits(Mips::FeatureMips32r2, "mips32r2"); 2528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveSetMips32R2(); 252936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 2530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Mips::FeatureMips64: 2531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines setFeatureBits(Mips::FeatureMips64, "mips64"); 2532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveSetMips64(); 253336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 2534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Mips::FeatureMips64r2: 2535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines setFeatureBits(Mips::FeatureMips64r2, "mips64r2"); 2536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveSetMips64R2(); 253736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 253836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 253936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 254036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 254136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 254236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::eatComma(StringRef ErrorStr) { 254336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().isNot(AsmToken::Comma)) { 254436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SMLoc Loc = getLexer().getLoc(); 254536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 254636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(Loc, ErrorStr); 254736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 254836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Parser.Lex(); // Eat the comma. 255036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 255136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 255236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) { 2554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Options.isReorder()) 2555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Warning(Loc, ".cpload in reorder section"); 2556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // FIXME: Warn if cpload is used in Mips16 mode. 2558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2559cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 2560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OperandMatchResultTy ResTy = ParseAnyRegister(Reg); 2561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 2562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines reportParseError("expected register containing function address"); 2563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 2564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 2565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2566cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 2567cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!RegOpnd.isGPRAsmReg()) { 2568cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError(RegOpnd.getStartLoc(), "invalid register"); 2569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 2570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 2571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2572cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg()); 2573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 2574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 2575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 257636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveCPSetup() { 257736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned FuncReg; 257836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Save; 257936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool SaveIsReg = true; 258036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2581cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 2582cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg); 2583cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ResTy == MatchOperand_NoMatch) { 2584cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("expected register containing function address"); 2585cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.eatToEndOfStatement(); 2586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 2590cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!FuncRegOpnd.isGPRAsmReg()) { 2591cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 2592cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.eatToEndOfStatement(); 2593cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2594cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2595cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2596cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FuncReg = FuncRegOpnd.getGPR32Reg(); 2597cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpReg.clear(); 259836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 259936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!eatComma("expected comma parsing directive")) 260036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 260136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2602cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ResTy = ParseAnyRegister(TmpReg); 2603cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ResTy == MatchOperand_NoMatch) { 260436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const AsmToken &Tok = Parser.getTok(); 260536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Tok.is(AsmToken::Integer)) { 260636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Save = Tok.getIntVal(); 260736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SaveIsReg = false; 260836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 2609cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 2610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("expected save register or stack offset"); 2611cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.eatToEndOfStatement(); 2612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2614cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 2615cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 2616cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!SaveOpnd.isGPRAsmReg()) { 2617cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 2618cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.eatToEndOfStatement(); 2619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Save = SaveOpnd.getGPR32Reg(); 2622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 262336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 262436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!eatComma("expected comma parsing directive")) 262536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 262636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 262736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Name; 262836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.parseIdentifier(Name)) 262936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reportParseError("expected identifier"); 263036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 263136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg); 2633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 2634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 263536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool MipsAsmParser::parseDirectiveNaN() { 2637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) { 2638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const AsmToken &Tok = Parser.getTok(); 2639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Tok.getString() == "2008") { 2641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Parser.Lex(); 2642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveNaN2008(); 2643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 2644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (Tok.getString() == "legacy") { 2645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Parser.Lex(); 2646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveNaNLegacy(); 2647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 2648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 2649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 2650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If we don't recognize the option passed to the .nan 2651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // directive (e.g. no option or unknown option), emit an error. 2652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines reportParseError("invalid option in .nan directive"); 265336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 265436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 265536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 265630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() { 265730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 265886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Get the next token. 265930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter const AsmToken &Tok = Parser.getTok(); 266030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 266130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Tok.getString() == "noat") { 266230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoAtDirective(); 266330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "at") { 266430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetAtDirective(); 2665cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (Tok.getString() == "fp") { 2666cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return parseSetFpDirective(); 266730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "reorder") { 266830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetReorderDirective(); 266930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "noreorder") { 267030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoReorderDirective(); 267130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "macro") { 267230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetMacroDirective(); 267330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomacro") { 267430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoMacroDirective(); 267536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Tok.getString() == "mips16") { 267636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return parseSetFeature(Mips::FeatureMips16); 267730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomips16") { 267836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return parseSetNoMips16Directive(); 267930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomicromips") { 268036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getTargetStreamer().emitDirectiveSetNoMicroMips(); 2681cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 268230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 268336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Tok.getString() == "micromips") { 2684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return parseSetFeature(Mips::FeatureMicroMips); 268536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Tok.getString() == "mips32r2") { 2686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return parseSetFeature(Mips::FeatureMips32r2); 268736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Tok.getString() == "mips64") { 2688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return parseSetFeature(Mips::FeatureMips64); 268936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Tok.getString() == "mips64r2") { 2690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return parseSetFeature(Mips::FeatureMips64r2); 269136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Tok.getString() == "dsp") { 2692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return parseSetFeature(Mips::FeatureDSP); 2693c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } else { 269486924b4182537745659f2660244f3402c1e1ca4dJack Carter // It is just an identifier, look for an assignment. 2695c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter parseSetAssignment(); 2696c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 269730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 2698801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 269930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 270030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 270130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 270236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// parseDataDirective 2703801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// ::= .word [ expression (, expression)* ] 270436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 2705801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 2706801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter for (;;) { 2707801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter const MCExpr *Value; 2708cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Value)) 2709801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return true; 2710801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 2711801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter getParser().getStreamer().EmitValue(Value, Size); 2712801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 2713801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().is(AsmToken::EndOfStatement)) 2714801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter break; 2715801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 2716801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter // FIXME: Improve diagnostic. 2717801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::Comma)) 2718801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return Error(L, "unexpected token in directive"); 2719801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 2720801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 2721801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 2722801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 2723801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 2724801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 2725801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter} 2726801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 27272263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic/// parseDirectiveGpWord 27282263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic/// ::= .gpword local_sym 27292263a2ca72e21206d45a69532004a0b17881e733Vladimir Medicbool MipsAsmParser::parseDirectiveGpWord() { 27302263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic const MCExpr *Value; 27312263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic // EmitGPRel32Value requires an expression, so we are using base class 27322263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic // method to evaluate the expression. 27332263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic if (getParser().parseExpression(Value)) 27342263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic return true; 27352263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic getParser().getStreamer().EmitGPRel32Value(Value); 27362263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic 2737c0fad4d9fdb1aebe029bcb54311fad7059b1a9e5Vladimir Medic if (getLexer().isNot(AsmToken::EndOfStatement)) 27382263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic return Error(getLexer().getLoc(), "unexpected token in directive"); 2739c0fad4d9fdb1aebe029bcb54311fad7059b1a9e5Vladimir Medic Parser.Lex(); // Eat EndOfStatement token. 27402263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic return false; 27412263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic} 27422263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic 274336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// parseDirectiveGpDWord 274436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= .gpdword local_sym 274536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveGpDWord() { 274636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *Value; 274736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // EmitGPRel64Value requires an expression, so we are using base class 274836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // method to evaluate the expression. 274936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getParser().parseExpression(Value)) 275036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 275136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getParser().getStreamer().EmitGPRel64Value(Value); 275236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 275336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) 275436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Error(getLexer().getLoc(), "unexpected token in directive"); 275536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); // Eat EndOfStatement token. 275636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 275736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 2758acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 275936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveOption() { 276036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the option token. 276136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AsmToken Tok = Parser.getTok(); 276236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // At the moment only identifiers are supported. 276336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Tok.isNot(AsmToken::Identifier)) { 276436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Error(Parser.getTok().getLoc(), "unexpected token in .option directive"); 276536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 276636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 276736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 276836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 276936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Option = Tok.getIdentifier(); 277036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 277136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Option == "pic0") { 277236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getTargetStreamer().emitDirectiveOptionPic0(); 277336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 277436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 277536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Error(Parser.getTok().getLoc(), 277636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "unexpected token in .option pic0 directive"); 277736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 277836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 277936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 278036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 278136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 278236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Option == "pic2") { 278336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getTargetStreamer().emitDirectiveOptionPic2(); 278436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.Lex(); 278536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 278636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Error(Parser.getTok().getLoc(), 278736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "unexpected token in .option pic2 directive"); 278836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 278936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 279036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 279136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 279236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 279336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Unknown option. 279436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Warning(Parser.getTok().getLoc(), "unknown option in .option directive"); 279536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 279636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 279736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 279836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// parseDirectiveModule 2800cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= .module oddspreg 2801cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= .module nooddspreg 2802cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= .module fp=value 2803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseDirectiveModule() { 2804cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCAsmLexer &Lexer = getLexer(); 2805cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc L = Lexer.getLoc(); 2806cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2807cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!getTargetStreamer().getCanHaveModuleDir()) { 2808cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // TODO : get a better message. 2809cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError(".module directive must appear before any code"); 2810cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2811cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2812cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2813cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Lexer.is(AsmToken::Identifier)) { 2814cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Option = Parser.getTok().getString(); 2815cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); 2816cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2817cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Option == "oddspreg") { 2818cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32()); 2819cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 2820cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2821cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) { 2822cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("Expected end of statement"); 2823cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2824cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2825cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2826cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2827cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (Option == "nooddspreg") { 2828cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isABI_O32()) { 2829cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Error(L, "'.module nooddspreg' requires the O32 ABI"); 2830cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2831cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2832cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2833cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32()); 2834cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 2835cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2836cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) { 2837cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("Expected end of statement"); 2838cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2839cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2840cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2841cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2842cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (Option == "fp") { 2843cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return parseDirectiveModuleFP(); 2844cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2845cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2846cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); 2847cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2848cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2849cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2850cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 2851cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2852cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// parseDirectiveModuleFP 2853cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= =32 2854cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= =xx 2855cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= =64 2856cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseDirectiveModuleFP() { 2857cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCAsmLexer &Lexer = getLexer(); 2858cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2859cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Lexer.isNot(AsmToken::Equal)) { 2860cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("unexpected token in statement"); 2861cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2862cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2863cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); // Eat '=' token. 2864cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2865cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsABIFlagsSection::FpABIKind FpABI; 2866cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!parseFpABIValue(FpABI, ".module")) 2867cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2868cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2869cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) { 2870cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("unexpected token in statement"); 2871cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2872cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2873cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2874cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Emit appropriate flags. 2875cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32()); 2876cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); // Consume the EndOfStatement. 2877cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2878cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 2879cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2880cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 2881cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Directive) { 2882cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCAsmLexer &Lexer = getLexer(); 2883cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2884cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Lexer.is(AsmToken::Identifier)) { 2885cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Value = Parser.getTok().getString(); 2886cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); 2887cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2888cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Value != "xx") { 2889cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("unsupported value, expected 'xx', '32' or '64'"); 2890cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2891cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2892cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2893cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isABI_O32()) { 2894cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("'" + Directive + " fp=xx' requires the O32 ABI"); 2895cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2896cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2897cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2898cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FpABI = MipsABIFlagsSection::FpABIKind::XX; 2899cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 2900cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2901cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2902cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Lexer.is(AsmToken::Integer)) { 2903cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned Value = Parser.getTok().getIntVal(); 2904cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Parser.Lex(); 2905cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2906cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Value != 32 && Value != 64) { 2907cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("unsupported value, expected 'xx', '32' or '64'"); 2908cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2909cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2910cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2911cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Value == 32) { 2912cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!isABI_O32()) { 2913cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines reportParseError("'" + Directive + " fp=32' requires the O32 ABI"); 2914cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2915cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2916cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2917cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FpABI = MipsABIFlagsSection::FpABIKind::S32; 2918cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else 2919cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines FpABI = MipsABIFlagsSection::FpABIKind::S64; 2920cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2921cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return true; 2922cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 2923cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 2924cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return false; 2925cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 2926cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 292736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 2928801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter StringRef IDVal = DirectiveID.getString(); 2929801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 2930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IDVal == ".cpload") 2931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return parseDirectiveCPLoad(DirectiveID.getLoc()); 293236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IDVal == ".dword") { 293336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines parseDataDirective(8, DirectiveID.getLoc()); 293436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 293536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 293636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 293786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (IDVal == ".ent") { 293886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 2939acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 2940acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 2941acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 2942acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 2943801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".end") { 294486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 2945acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 2946acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 2947acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 2948acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 2949801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".frame") { 295086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 2951cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 2952acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 2953acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 2954acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 2955801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".set") { 295630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseDirectiveSet(); 2957acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 2958acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 2959801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".fmask") { 296086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 2961cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 2962acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 2963acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 2964acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 2965801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".mask") { 296686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 2967cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 2968acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 2969acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 2970acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 2971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IDVal == ".nan") 2972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return parseDirectiveNaN(); 2973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2974801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".gpword") { 29752263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic parseDirectiveGpWord(); 2976acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 2977acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 2978acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 297936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IDVal == ".gpdword") { 298036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines parseDirectiveGpDWord(); 298136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 298236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 298336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2984801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".word") { 298536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines parseDataDirective(4, DirectiveID.getLoc()); 2986801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 2987801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 2988801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 298936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IDVal == ".option") 299036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return parseDirectiveOption(); 299136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 299236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IDVal == ".abicalls") { 299336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getTargetStreamer().emitDirectiveAbiCalls(); 299436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 299536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Error(Parser.getTok().getLoc(), "unexpected token in directive"); 299636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Clear line 299736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parser.eatToEndOfStatement(); 299836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 299936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 300036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 3001a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling 300236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IDVal == ".cpsetup") 300336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return parseDirectiveCPSetup(); 3004a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling 3005cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (IDVal == ".module") 3006cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return parseDirectiveModule(); 3007cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 3008fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 3009fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 3010fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 3011fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() { 3012fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 3013fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 3014fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 3015fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 3016fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 3017ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 3018ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER 3019ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION 3020ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc" 3021