1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 3fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// The LLVM Compiler Infrastructure 4fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 5fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// This file is distributed under the University of Illinois Open Source 6fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// License. See LICENSE.TXT for details. 7fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 8fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//===----------------------------------------------------------------------===// 9fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 10fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h" 11ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h" 12ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/ADT/StringSwitch.h" 13ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h" 14ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h" 15ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h" 19ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h" 20ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h" 2172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCTargetAsmParser.h" 22ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/Support/TargetRegistry.h" 23c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter#include "llvm/ADT/APInt.h" 24fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 25fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm; 26fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 27fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace { 2830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions { 2930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic: 3030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter MipsAssemblerOptions(): 3130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter aTReg(1), reorder(true), macro(true) { 3230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 3330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 3430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter unsigned getATRegNum() {return aTReg;} 3530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool setATReg(unsigned Reg); 36ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 3730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool isReorder() {return reorder;} 3830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setReorder() {reorder = true;} 3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setNoreorder() {reorder = false;} 4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 4130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool isMacro() {return macro;} 4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setMacro() {macro = true;} 4330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setNomacro() {macro = false;} 4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 4530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate: 4630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter unsigned aTReg; 4730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool reorder; 4830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool macro; 4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}; 5030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 5130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 5230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace { 53fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser { 5472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter enum FpFormatTy { 56f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_NONE = -1, 57f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_S, 58f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_D, 59f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_L, 60f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_W 61f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } FpFormat; 62f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCSubtargetInfo &STI; 64ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &Parser; 6510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter MipsAssemblerOptions Options; 6630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 6772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER 6872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc" 6972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 7084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 71fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 7284125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 7384125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm); 74fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 75fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 76fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 776a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 786a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier SMLoc NameLoc, 7972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka SmallVectorImpl<MCParsedAsmOperand*> &Operands); 80fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 81fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseDirective(AsmToken DirectiveID); 82fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 83ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsAsmParser::OperandMatchResultTy 847231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 857231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic int RegKind); 86088483627720acb58c96951b7b634f67312c7272Vladimir Medic 87088483627720acb58c96951b7b634f67312c7272Vladimir Medic MipsAsmParser::OperandMatchResultTy 88ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 89ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 90ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 911858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 92ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 93ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 941858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 95ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 96ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 97ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 98ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 99ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 101ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 102ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 103ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 104038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 10590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic MipsAsmParser::OperandMatchResultTy 10690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 10790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 10890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic MipsAsmParser::OperandMatchResultTy 10990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 11090b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 11190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic MipsAsmParser::OperandMatchResultTy 11290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 11390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 114b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic MipsAsmParser::OperandMatchResultTy 115b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 116b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 117a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka MipsAsmParser::OperandMatchResultTy 118a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka parseACRegsDSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 119a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 120c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1217231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic unsigned RegKind); 122c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 123ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 124ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic); 125ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 126ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int tryParseRegister(bool is64BitReg); 127ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 128ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 129ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool is64BitReg); 130ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1319d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter bool needsExpansion(MCInst &Inst); 1329d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 1339d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter void expandInstruction(MCInst &Inst, SMLoc IDLoc, 1342490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 1359d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 1362490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 1372f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 1392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 14125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter void expandMemInst(MCInst &Inst, SMLoc IDLoc, 14225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions, 14325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool isLoad,bool isImmOpnd); 14430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool reportParseError(StringRef ErrorMsg); 14530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 147ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool parseRelocOperand(const MCExpr *&Res); 14830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 1508afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 1518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool isEvaluated(const MCExpr *Expr); 15230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseDirectiveSet(); 15330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 15430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetAtDirective(); 15530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoAtDirective(); 15630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetMacroDirective(); 15730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoMacroDirective(); 15830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetReorderDirective(); 15930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoReorderDirective(); 16030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 161c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter bool parseSetAssignment(); 162c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 163801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter bool parseDirectiveWord(unsigned Size, SMLoc L); 164801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 166f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 167ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool isMips64() const { 168ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 169ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 170ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 171f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool isFP64() const { 172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 173f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 174f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 175ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int matchRegisterName(StringRef Symbol, bool is64BitReg); 176ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 17799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int matchCPURegisterName(StringRef Symbol); 17899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 179ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 180ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1817231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic int matchFPURegisterName(StringRef Name, FpFormatTy Format); 1827231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 183f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(FpFormatTy Format) { 184f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = Format; 185f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 186f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 187f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setDefaultFpFormat(); 188f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 189f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(StringRef Format); 190f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 191f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormatTy getFpFormat() {return FpFormat;} 192f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 19386924b4182537745659f2660244f3402c1e1ca4dJack Carter unsigned getReg(int RC, int RegNo); 194038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 19599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int getATReg(); 19625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 19725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool processInstruction(MCInst &Inst, SMLoc IDLoc, 19825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions); 199fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic: 200fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 201ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter : MCTargetAsmParser(), STI(sti), Parser(parser) { 202ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Initialize the set of available features. 203ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 204fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola } 205fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 206ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &getParser() const { return Parser; } 207ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmLexer &getLexer() const { return Parser.getLexer(); } 208ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 209fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}; 210fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 211fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 21272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace { 21372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 21472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine 21572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction. 21672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand { 217ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 218ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic: 219ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter enum RegisterKind { 220ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_None, 2211858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka Kind_GPR32, 2221858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka Kind_GPR64, 223ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_HWRegs, 224ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_HW64Regs, 225ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_FGR32Regs, 226ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_FGR64Regs, 22799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter Kind_AFGR64Regs, 228b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic Kind_CCRRegs, 229a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka Kind_FCCRegs, 230a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka Kind_ACRegsDSP 231ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter }; 232ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 233ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate: 23472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka enum KindTy { 23572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CondCode, 23672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CoprocNum, 23772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Immediate, 23872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Memory, 23972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_PostIndexRegister, 24072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Register, 24172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Token 24272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } Kind; 24372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 24472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 245ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 246a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token { 247a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const char *Data; 248a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Length; 249a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 250a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 251a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp { 252a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned RegNum; 253a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher RegisterKind Kind; 254a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 255a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 256a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp { 257a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Val; 258a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 259a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 260a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp { 261a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Base; 262a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Off; 263a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 264a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 265ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter union { 266a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token Tok; 267a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp Reg; 268a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp Imm; 269a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp Mem; 270ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter }; 271ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 272ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc StartLoc, EndLoc; 273ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 27472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic: 27572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addRegOperands(MCInst &Inst, unsigned N) const { 276ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 277ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateReg(getReg())); 27872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 279ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 28072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 281ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Add as immediate when possible. Null MCExpr = 0. 282ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Expr == 0) 283ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(0)); 284ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 285ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 286ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else 287ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateExpr(Expr)); 28872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 289ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 29072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addImmOperands(MCInst &Inst, unsigned N) const { 291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 292ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *Expr = getImm(); 29386924b4182537745659f2660244f3402c1e1ca4dJack Carter addExpr(Inst, Expr); 29472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 295ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 29672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addMemOperands(MCInst &Inst, unsigned N) const { 2976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert(N == 2 && "Invalid number of operands!"); 2986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 2996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Inst.addOperand(MCOperand::CreateReg(getMemBase())); 3006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 3016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Expr = getMemOff(); 30286924b4182537745659f2660244f3402c1e1ca4dJack Carter addExpr(Inst, Expr); 30372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 30472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 30572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isReg() const { return Kind == k_Register; } 30672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isImm() const { return Kind == k_Immediate; } 30772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isToken() const { return Kind == k_Token; } 30872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isMem() const { return Kind == k_Memory; } 30972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 31072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka StringRef getToken() const { 31172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert(Kind == k_Token && "Invalid access!"); 312ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return StringRef(Tok.Data, Tok.Length); 31372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 31472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 31572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka unsigned getReg() const { 31672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert((Kind == k_Register) && "Invalid access!"); 317ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Reg.RegNum; 318ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 319ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 320ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void setRegKind(RegisterKind RegKind) { 321ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 322ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Reg.Kind = RegKind; 323ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 324ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *getImm() const { 326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert((Kind == k_Immediate) && "Invalid access!"); 327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Imm.Val; 328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 3306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter unsigned getMemBase() const { 3316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 3326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Base; 3336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 3356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *getMemOff() const { 3366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 3376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Off; 3386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Token); 342ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Data = Str.data(); 343ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Length = Str.size(); 344ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 345ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = S; 346ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 347ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 348ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 349ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 350ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Register); 351ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Reg.RegNum = RegNum; 352ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 353ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 354ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 355ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 356ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 357ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 358ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Immediate); 359ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Imm.Val = Val; 360ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 361ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 362ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 36372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 36472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 3656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 3666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc S, SMLoc E) { 3676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand *Op = new MipsOperand(k_Memory); 3686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Base = Base; 3696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Off = Off; 3706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->StartLoc = S; 3716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->EndLoc = E; 3726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Op; 3736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 3751858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka bool isGPR32Asm() const { 3761858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka return Kind == k_Register && Reg.Kind == Kind_GPR32; 377ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 378dd5fe2ffc6f564192876065d2617ecbc18d03f23Vladimir Medic void addRegAsmOperands(MCInst &Inst, unsigned N) const { 379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 381ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 3821858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka bool isGPR64Asm() const { 3831858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka return Kind == k_Register && Reg.Kind == Kind_GPR64; 384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 385ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 386ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isHWRegsAsm() const { 387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 388ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_HWRegs; 389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isHW64RegsAsm() const { 392ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 393ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_HW64Regs; 394ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 395ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 396ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isCCRAsm() const { 397ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 398ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_CCRRegs; 399ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 400ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 40190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic bool isAFGR64Asm() const { 40290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs; 40390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic } 40490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 40590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic bool isFGR64Asm() const { 40690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return Kind == k_Register && Reg.Kind == Kind_FGR64Regs; 40790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic } 40890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 40990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic bool isFGR32Asm() const { 41090b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs; 41190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic } 41290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 413b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic bool isFCCRegsAsm() const { 414b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs; 415b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic } 416b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 417a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka bool isACRegsDSPAsm() const { 418a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka return Kind == k_Register && Reg.Kind == Kind_ACRegsDSP; 419a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka } 420a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 421ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getStartLoc - Get the location of the first token of this operand. 42286924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc getStartLoc() const { 42386924b4182537745659f2660244f3402c1e1ca4dJack Carter return StartLoc; 42486924b4182537745659f2660244f3402c1e1ca4dJack Carter } 425ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getEndLoc - Get the location of the last token of this operand. 42686924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc getEndLoc() const { 42786924b4182537745659f2660244f3402c1e1ca4dJack Carter return EndLoc; 42886924b4182537745659f2660244f3402c1e1ca4dJack Carter } 429ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 43072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka virtual void print(raw_ostream &OS) const { 43172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka llvm_unreachable("unimplemented!"); 43272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 43386924b4182537745659f2660244f3402c1e1ca4dJack Carter}; // class MipsOperand 43486924b4182537745659f2660244f3402c1e1ca4dJack Carter} // namespace 43572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 43625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm { 43725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[]; 43825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 43925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 44025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return MipsInsts[Opcode]; 44125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 44225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 44325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 4448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter SmallVectorImpl<MCInst> &Instructions) { 44525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 44625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Inst.setLoc(IDLoc); 44797265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter if (MCID.hasDelaySlot() && Options.isReorder()) { 44897265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter // If this instruction has a delay slot and .set reorder is active, 44997265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter // emit a NOP after it. 45097265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter Instructions.push_back(Inst); 45197265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter MCInst NopInst; 45297265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.setOpcode(Mips::SLL); 45397265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 45497265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 45597265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter NopInst.addOperand(MCOperand::CreateImm(0)); 45697265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter Instructions.push_back(NopInst); 45797265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter return false; 45897265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter } 45997265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter 46025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MCID.mayLoad() || MCID.mayStore()) { 46125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Check the offset of memory operand, if it is a symbol 46286924b4182537745659f2660244f3402c1e1ca4dJack Carter // reference or immediate we may have to expand instructions. 46386924b4182537745659f2660244f3402c1e1ca4dJack Carter for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 46425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 46586924b4182537745659f2660244f3402c1e1ca4dJack Carter if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) 46686924b4182537745659f2660244f3402c1e1ca4dJack Carter || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 46725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCOperand &Op = Inst.getOperand(i); 46825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (Op.isImm()) { 46925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter int MemOffset = Op.getImm(); 47025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MemOffset < -32768 || MemOffset > 32767) { 47186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Offset can't exceed 16bit value. 47286924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 47325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 47425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 47525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } else if (Op.isExpr()) { 47625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *Expr = Op.getExpr(); 47786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Expr->getKind() == MCExpr::SymbolRef) { 47825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR = 4798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter static_cast<const MCSymbolRefExpr*>(Expr); 48025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (SR->getKind() == MCSymbolRefExpr::VK_None) { 48186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Expand symbol. 48286924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 48325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 48425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 4858afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else if (!isEvaluated(Expr)) { 48686924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 4878afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 48825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 48925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 49025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 49186924b4182537745659f2660244f3402c1e1ca4dJack Carter } // for 49286924b4182537745659f2660244f3402c1e1ca4dJack Carter } // if load/store 49325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 49425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (needsExpansion(Inst)) 49525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter expandInstruction(Inst, IDLoc, Instructions); 49625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else 49725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(Inst); 49825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 49925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 50025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 50125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 5029d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) { 5039d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 50486924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (Inst.getOpcode()) { 50586924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadImm32Reg: 50686924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Imm: 50786924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Reg: 50886924b4182537745659f2660244f3402c1e1ca4dJack Carter return true; 50986924b4182537745659f2660244f3402c1e1ca4dJack Carter default: 51086924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 5119d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 5129d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 5132490dc650895149423bb59538dc03ca352222702Jack Carter 5149d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 51586924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 51686924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (Inst.getOpcode()) { 51786924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadImm32Reg: 51886924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadImm(Inst, IDLoc, Instructions); 51986924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Imm: 52086924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadAddressImm(Inst, IDLoc, Instructions); 52186924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Reg: 52286924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadAddressReg(Inst, IDLoc, Instructions); 52386924b4182537745659f2660244f3402c1e1ca4dJack Carter } 5249d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 5252490dc650895149423bb59538dc03ca352222702Jack Carter 5269d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 52786924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 5282490dc650895149423bb59538dc03ca352222702Jack Carter MCInst tmpInst; 5299d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &ImmOp = Inst.getOperand(1); 5302f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 5319d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &RegOp = Inst.getOperand(0); 5329d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter assert(RegOp.isReg() && "expected register operand kind"); 5339d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 5349d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter int ImmValue = ImmOp.getImm(); 5352490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.setLoc(IDLoc); 53686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (0 <= ImmValue && ImmValue <= 65535) { 53786924b4182537745659f2660244f3402c1e1ca4dJack Carter // For 0 <= j <= 65535. 5389d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => ori d,$zero,j 539ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5402490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 54186924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 5422490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5439d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 54486924b4182537745659f2660244f3402c1e1ca4dJack Carter } else if (ImmValue < 0 && ImmValue >= -32768) { 54586924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j < 0. 5469d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => addiu d,$zero,j 547ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5482490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 54986924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 5502490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5519d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5529d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } else { 55386924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 5549d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => lui d,hi16(j) 5552f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter // ori d,d,lo16(j) 556ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5572490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5582490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 5599d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5602490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.clear(); 561ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5622490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5632490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5642490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 5652490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.setLoc(IDLoc); 5669d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5679d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 5689d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 5692490dc650895149423bb59538dc03ca352222702Jack Carter 5702f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 57186924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 5722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 5732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(2); 5742f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 5752f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &SrcRegOp = Inst.getOperand(1); 5762f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(SrcRegOp.isReg() && "expected register operand kind"); 5772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &DstRegOp = Inst.getOperand(0); 5782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(DstRegOp.isReg() && "expected register operand kind"); 5792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 58086924b4182537745659f2660244f3402c1e1ca4dJack Carter if (-32768 <= ImmValue && ImmValue <= 65535) { 58186924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j <= 65535. 58286924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j(s) => addiu d,s,j 583ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5852f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 5862f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5872f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5882f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 58986924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 59086924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j(s) => lui d,hi16(j) 59186924b4182537745659f2660244f3402c1e1ca4dJack Carter // ori d,d,lo16(j) 59286924b4182537745659f2660244f3402c1e1ca4dJack Carter // addu d,d,s 593ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5942f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5952f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 5962f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5972f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 598ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5992f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 6002f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 6012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 6022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 6032f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 6042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDu); 6052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 6062f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 6072f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 6082f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 6092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 6102f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 6112f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 6122f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 61386924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 6142f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 6152f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(1); 6162f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 6172f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &RegOp = Inst.getOperand(0); 6182f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(RegOp.isReg() && "expected register operand kind"); 6192f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 62086924b4182537745659f2660244f3402c1e1ca4dJack Carter if (-32768 <= ImmValue && ImmValue <= 65535) { 62186924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j <= 65535. 62286924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j => addiu d,$zero,j 6232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDiu); 6242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 62586924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 6262f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 6272f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 6282f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 62986924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 63086924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j => lui d,hi16(j) 63186924b4182537745659f2660244f3402c1e1ca4dJack Carter // ori d,d,lo16(j) 632ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 6332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 6342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 6352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 6362f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 637ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 6382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 6392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 6402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 6412f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 6422f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 6432f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 6442f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 64525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 64686924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) { 64725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR; 64825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCInst TempInst; 64986924b4182537745659f2660244f3402c1e1ca4dJack Carter unsigned ImmOffset, HiOffset, LoOffset; 65025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *ExprOffset; 65125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned TmpRegNum; 6521858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID 6531858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka : Mips::GPR32RegClassID, getATReg()); 65486924b4182537745659f2660244f3402c1e1ca4dJack Carter // 1st operand is either the source or destination register. 65525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 65625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned RegOpNum = Inst.getOperand(0).getReg(); 65786924b4182537745659f2660244f3402c1e1ca4dJack Carter // 2nd operand is the base register. 65825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 65925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned BaseRegNum = Inst.getOperand(1).getReg(); 66086924b4182537745659f2660244f3402c1e1ca4dJack Carter // 3rd operand is either an immediate or expression. 66125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) { 66225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 66325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ImmOffset = Inst.getOperand(2).getImm(); 66425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter LoOffset = ImmOffset & 0x0000ffff; 66525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset = (ImmOffset & 0xffff0000) >> 16; 66686924b4182537745659f2660244f3402c1e1ca4dJack Carter // If msb of LoOffset is 1(negative number) we must increment HiOffset. 66725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (LoOffset & 0x8000) 66825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset++; 66986924b4182537745659f2660244f3402c1e1ca4dJack Carter } else 67025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ExprOffset = Inst.getOperand(2).getExpr(); 67186924b4182537745659f2660244f3402c1e1ca4dJack Carter // All instructions will have the same location. 67225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setLoc(IDLoc); 67325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // 1st instruction in expansion is LUi. For load instruction we can use 67425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // the dst register as a temporary if base and dst are different, 67586924b4182537745659f2660244f3402c1e1ca4dJack Carter // but for stores we must use $at. 67686924b4182537745659f2660244f3402c1e1ca4dJack Carter TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 67725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::LUi); 67825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 67925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 68025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 68125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 68225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 68325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SR = static_cast<const MCSymbolRefExpr*>(ExprOffset); 68486924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 68586924b4182537745659f2660244f3402c1e1ca4dJack Carter SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 68686924b4182537745659f2660244f3402c1e1ca4dJack Carter getContext()); 68725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 6888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else { 68986924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 6908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 69125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 69225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 69386924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add the instruction to the list. 69425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 69586924b4182537745659f2660244f3402c1e1ca4dJack Carter // Prepare TempInst for next instruction. 69625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 69786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add temp register to base. 69825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::ADDu); 69925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 70025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 70125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 70225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 70325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 7048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter // And finaly, create original instruction with low part 70586924b4182537745659f2660244f3402c1e1ca4dJack Carter // of offset and new base. 70625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Inst.getOpcode()); 70725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 70825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 70925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 71025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 71125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 71225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 71386924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 71486924b4182537745659f2660244f3402c1e1ca4dJack Carter SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 71586924b4182537745659f2660244f3402c1e1ca4dJack Carter getContext()); 71625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 7178afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else { 71886924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 7198afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 72025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 72125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 72225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 72325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 72425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 72525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 726fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 72784125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 728fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 72984125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 73084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm) { 731ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCInst Inst; 73225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVector<MCInst, 8> Instructions; 7336e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 73484125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MatchingInlineAsm); 735ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 736ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (MatchResult) { 73786924b4182537745659f2660244f3402c1e1ca4dJack Carter default: 73886924b4182537745659f2660244f3402c1e1ca4dJack Carter break; 739ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_Success: { 74086924b4182537745659f2660244f3402c1e1ca4dJack Carter if (processInstruction(Inst, IDLoc, Instructions)) 74125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return true; 74286924b4182537745659f2660244f3402c1e1ca4dJack Carter for (unsigned i = 0; i < Instructions.size(); i++) 74325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Out.EmitInstruction(Instructions[i]); 744ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 745ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 746ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MissingFeature: 747ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 748ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 749ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_InvalidOperand: { 750ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc ErrorLoc = IDLoc; 751ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo != ~0U) { 752ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo >= Operands.size()) 753ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "too few operands for instruction"); 754ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 75586924b4182537745659f2660244f3402c1e1ca4dJack Carter ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc(); 75686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (ErrorLoc == SMLoc()) 75786924b4182537745659f2660244f3402c1e1ca4dJack Carter ErrorLoc = IDLoc; 758ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 759ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 760ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(ErrorLoc, "invalid operand for instruction"); 761ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 762ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MnemonicFail: 763ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "invalid instruction"); 764ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 765fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 766fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 767fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 76899e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) { 769572e1bd109518f80b54d229de10699c4603944c3David Chisnall int CC; 77099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 77199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (Name == "at") 77299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return getATReg(); 77399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 774572e1bd109518f80b54d229de10699c4603944c3David Chisnall CC = StringSwitch<unsigned>(Name) 77599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("zero", 0) 77699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a0", 4) 77799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a1", 5) 77899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a2", 6) 77999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a3", 7) 78099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("v0", 2) 78199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("v1", 3) 78299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s0", 16) 78399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s1", 17) 78499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s2", 18) 78599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s3", 19) 78699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s4", 20) 78799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s5", 21) 78899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s6", 22) 78999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s7", 23) 79099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("k0", 26) 79199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("k1", 27) 79299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("sp", 29) 79399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("fp", 30) 79499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("gp", 28) 79599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("ra", 31) 79699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t0", 8) 79799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t1", 9) 79899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t2", 10) 79999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t3", 11) 80099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t4", 12) 80199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t5", 13) 80299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t6", 14) 80399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t7", 15) 80499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t8", 24) 80599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t9", 25) 80699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Default(-1); 80799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 80886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Although SGI documentation just cuts out t0-t3 for n32/n64, 80999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 81099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 81186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (isMips64() && 8 <= CC && CC <= 11) 81299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter CC += 4; 81399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 81499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (CC == -1 && isMips64()) 815572e1bd109518f80b54d229de10699c4603944c3David Chisnall CC = StringSwitch<unsigned>(Name) 81699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a4", 8) 81799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a5", 9) 81899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a6", 10) 81999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a7", 11) 82099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("kt0", 26) 82199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("kt1", 27) 82299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s8", 30) 823572e1bd109518f80b54d229de10699c4603944c3David Chisnall .Default(-1); 824572e1bd109518f80b54d229de10699c4603944c3David Chisnall 82599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return CC; 82699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter} 82786924b4182537745659f2660244f3402c1e1ca4dJack Carter 8287231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medicint MipsAsmParser::matchFPURegisterName(StringRef Name, FpFormatTy Format) { 829ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Name[0] == 'f') { 831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef NumString = Name.substr(1); 832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter unsigned IntVal; 83386924b4182537745659f2660244f3402c1e1ca4dJack Carter if (NumString.getAsInteger(10, IntVal)) 83486924b4182537745659f2660244f3402c1e1ca4dJack Carter return -1; // This is not an integer. 835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (IntVal > 31) 836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR32RegClassID, IntVal); 840f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_D) { 84186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (isFP64()) { 842f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR64RegClassID, IntVal); 843f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 84486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Only even numbers available as register pairs. 84586924b4182537745659f2660244f3402c1e1ca4dJack Carter if ((IntVal > 31) || (IntVal % 2 != 0)) 846f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 84786924b4182537745659f2660244f3402c1e1ca4dJack Carter return getReg(Mips::AFGR64RegClassID, IntVal / 2); 848f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 849f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 850ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 851ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 85286924b4182537745659f2660244f3402c1e1ca4dJack Carter 8537231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medicint MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 8547231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 8557231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic if (Name.equals("fcc0")) 8567231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic return Mips::FCC0; 8577231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 8587231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic int CC; 8597231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic CC = matchCPURegisterName(Name); 8607231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic if (CC != -1) 8611858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID 8621858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka : Mips::GPR32RegClassID); 8637231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic return matchFPURegisterName(Name, getFpFormat()); 8647231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic} 8657231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 866f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() { 867f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 868f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (isMips64() || isFP64()) 869f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_D; 870f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else 871f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_S; 872f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 873f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 874f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) { 875f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 876f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 877f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".s", FP_FORMAT_S) 878f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".d", FP_FORMAT_D) 879f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".l", FP_FORMAT_L) 880f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".w", FP_FORMAT_W) 881f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(FP_FORMAT_NONE); 882f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 88430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) { 88530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Reg > 31) 88630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 88730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 88830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter aTReg = Reg; 88930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 89030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 89130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 89299e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::getATReg() { 89399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return Options.getATRegNum(); 89430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 89530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 89686924b4182537745659f2660244f3402c1e1ca4dJack Carterunsigned MipsAsmParser::getReg(int RC, int RegNo) { 89799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 898ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 899ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 900ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 901ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 902ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNum > 31) 903ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 904ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 905ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return getReg(RegClass, RegNum); 906ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 907ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 908ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::tryParseRegister(bool is64BitReg) { 909ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const AsmToken &Tok = Parser.getTok(); 910ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNum = -1; 911ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 912ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Tok.is(AsmToken::Identifier)) { 913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter std::string lowerCase = Tok.getString().lower(); 914ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNum = matchRegisterName(lowerCase, is64BitReg); 915ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } else if (Tok.is(AsmToken::Integer)) 9169d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 9171858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID); 918ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return RegNum; 919ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 920ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 92186924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::tryParseRegisterOperand( 92286924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) { 923ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 924ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 925ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNo = -1; 926f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 927ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNo = tryParseRegister(is64BitReg); 928ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNo == -1) 929ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 930ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 931ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(MipsOperand::CreateReg(RegNo, S, 93286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc())); 933ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat register token. 934ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 935ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 936ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 937ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 938ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic) { 9399d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // Check if the current operand has a custom associated parser, if so, try to 9409d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // custom parse the operand, or fallback to the general approach. 941ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 942ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_Success) 943ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 944ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // If there wasn't a custom match, try the generic matcher below. Otherwise, 945ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // there was a match, but an error occurred, in which case, just return that 946ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // the operand parsing failed. 947ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_ParseFail) 948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 949ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (getLexer().getKind()) { 951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter default: 952ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 953ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 954ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Dollar: { 95586924b4182537745659f2660244f3402c1e1ca4dJack Carter // Parse the register. 956ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 957ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat dollar token. 95886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Parse the register operand. 959ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (!tryParseRegisterOperand(Operands, isMips64())) { 960ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().is(AsmToken::LParen)) { 96186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check if it is indexed addressing operand. 962ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken("(", S)); 96386924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the parenthesis. 964ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::Dollar)) 965ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 966ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 96786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the dollar 968ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (tryParseRegisterOperand(Operands, isMips64())) 969ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 970ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 971ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (!getLexer().is(AsmToken::RParen)) 972ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 973ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 974ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter S = Parser.getTok().getLoc(); 975ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken(")", S)); 976ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); 977ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 978ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 979ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 98086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Maybe it is a symbol reference. 981ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Identifier; 982cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (Parser.parseIdentifier(Identifier)) 983ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 984ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 985ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 986ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 98738539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 988ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 98986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Otherwise create a symbol reference. 9906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 991ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter getContext()); 992ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 993ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 994ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 995ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 996ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Identifier: 997c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // Look for the existing symbol, we should check if 99886924b4182537745659f2660244f3402c1e1ca4dJack Carter // we need to assigne the propper RegisterKind. 99986924b4182537745659f2660244f3402c1e1ca4dJack Carter if (searchSymbolAlias(Operands, MipsOperand::Kind_None)) 100086924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 100186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Else drop to expression parsing. 1002ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::LParen: 1003ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Minus: 1004ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Plus: 1005ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Integer: 1006ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::String: { 100786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Quoted label names. 1008ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *IdVal; 1009ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 1010cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(IdVal)) 1011ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 1012ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1013ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1014ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 1015ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 10166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Percent: { 101786924b4182537745659f2660244f3402c1e1ca4dJack Carter // It is a symbol reference or constant expression. 10186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 101986924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1020ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (parseRelocOperand(IdVal)) 10216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 10226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1023ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1024ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 10256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 10266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 102730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // case AsmToken::Percent 102830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // switch(getLexer().getKind()) 1029fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 1030fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1031fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 10328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterconst MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 10338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter StringRef RelocStr) { 10348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter const MCExpr *Res; 103586924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check the type of the expression. 10368afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 103786924b4182537745659f2660244f3402c1e1ca4dJack Carter // It's a constant, evaluate lo or hi value. 10388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (RelocStr == "lo") { 10398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter short Val = MCE->getValue(); 10408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Res = MCConstantExpr::Create(Val, getContext()); 10418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else if (RelocStr == "hi") { 10428afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter int Val = MCE->getValue(); 10438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter int LoSign = Val & 0x8000; 10448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Val = (Val & 0xffff0000) >> 16; 10458afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter // Lower part is treated as a signed int, so if it is negative 104686924b4182537745659f2660244f3402c1e1ca4dJack Carter // we must add 1 to the hi part to compensate. 10478afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (LoSign) 10488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Val++; 10498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Res = MCConstantExpr::Create(Val, getContext()); 1050ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov } else { 1051ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov llvm_unreachable("Invalid RelocStr value"); 10528afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 105386924b4182537745659f2660244f3402c1e1ca4dJack Carter return Res; 10548afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 105786924b4182537745659f2660244f3402c1e1ca4dJack Carter // It's a symbol, create a symbolic expression from the symbol. 10588afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter StringRef Symbol = MSRE->getSymbol().getName(); 10598afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 106086924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 10618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Res; 10628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10648afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 106586924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 106686924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 10678afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 10688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Res; 10698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10708afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 107286924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 107386924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 107486924b4182537745659f2660244f3402c1e1ca4dJack Carter return Res; 10758afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 107686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Just return the original expression. 10778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Expr; 10788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter} 10798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10808afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 10818afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10828afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter switch (Expr->getKind()) { 10838afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Constant: 10848afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return true; 10858afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::SymbolRef: 10868afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 10878afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Binary: 10888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 10898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (!isEvaluated(BE->getLHS())) 10908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 10918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return isEvaluated(BE->getRHS()); 10928afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Unary: 10948afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 10958afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter default: 10968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 10978afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10988afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 10998afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter} 11006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 110186924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 110286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the % token. 110386924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 11046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok.isNot(AsmToken::Identifier)) 11056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 11066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 110738539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer std::string Str = Tok.getIdentifier().str(); 11086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 110986924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the identifier. 111086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Now make an expression from the rest of the operand. 11116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 1112ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc EndLoc; 11136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::LParen) { 11156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter while (1) { 111686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '(' token. 11176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::Percent) { 111886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the % token. 11196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &nextTok = Parser.getTok(); 11206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (nextTok.isNot(AsmToken::Identifier)) 11216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 112238539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += "(%"; 112338539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += nextTok.getIdentifier(); 112486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the identifier. 11256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() != AsmToken::LParen) 11266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 11276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 11286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter break; 11296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 113086924b4182537745659f2660244f3402c1e1ca4dJack Carter if (getParser().parseParenExpression(IdVal, EndLoc)) 11316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 11326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1133ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter while (getLexer().getKind() == AsmToken::RParen) 113486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the ')' token. 11356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 113786924b4182537745659f2660244f3402c1e1ca4dJack Carter return true; // Parenthesis must follow the relocation operand. 11386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 113986924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = evaluateRelocExpr(IdVal, Str); 11408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 11416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 11426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1143ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1144ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc &EndLoc) { 1145ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StartLoc = Parser.getTok().getLoc(); 1146ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNo = tryParseRegister(isMips64()); 1147ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter EndLoc = Parser.getTok().getLoc(); 114886924b4182537745659f2660244f3402c1e1ca4dJack Carter return (RegNo == (unsigned) -1); 1149ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1150ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 11518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1152ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 11538afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool Result = true; 11548afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 11558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter while (getLexer().getKind() == AsmToken::LParen) 11568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 1157ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 115886924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (getLexer().getKind()) { 11596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter default: 11606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 116125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter case AsmToken::Identifier: 11628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case AsmToken::LParen: 11636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Integer: 11646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Minus: 11656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Plus: 11668afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (isParenExpr) 116786924b4182537745659f2660244f3402c1e1ca4dJack Carter Result = getParser().parseParenExpression(Res, S); 11688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter else 11698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Result = (getParser().parseExpression(Res)); 117086924b4182537745659f2660244f3402c1e1ca4dJack Carter while (getLexer().getKind() == AsmToken::RParen) 11718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 117286924b4182537745659f2660244f3402c1e1ca4dJack Carter break; 1173ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter case AsmToken::Percent: 11748afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Result = parseRelocOperand(Res); 11756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 11768afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Result; 11776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 11786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1179ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 118086924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 11816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal = 0; 1183ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 11848afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool isParenExpr = false; 118586924b4182537745659f2660244f3402c1e1ca4dJack Carter // First operand is the offset. 1186ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter S = Parser.getTok().getLoc(); 11876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (getLexer().getKind() == AsmToken::LParen) { 11898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 11908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter isParenExpr = true; 11918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 11926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (getLexer().getKind() != AsmToken::Dollar) { 119486924b4182537745659f2660244f3402c1e1ca4dJack Carter if (parseMemOffset(IdVal, isParenExpr)) 11958afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_ParseFail; 11968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 119786924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get the next token. 11988afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Tok.isNot(AsmToken::LParen)) { 11998afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 12008afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Mnemonic->getToken() == "la") { 12018afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter SMLoc E = SMLoc::getFromPointer( 120286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc().getPointer() - 1); 12038afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 12048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_Success; 12058afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 12068afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Tok.is(AsmToken::EndOfStatement)) { 12078afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter SMLoc E = SMLoc::getFromPointer( 120886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc().getPointer() - 1); 12098afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 121086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Zero register assumed, add a memory operand with ZERO as its base. 121186924b4182537745659f2660244f3402c1e1ca4dJack Carter Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64 121286924b4182537745659f2660244f3402c1e1ca4dJack Carter : Mips::ZERO, 121386924b4182537745659f2660244f3402c1e1ca4dJack Carter IdVal, S, E)); 12148afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_Success; 12158afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 12168afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Error(Parser.getTok().getLoc(), "'(' expected"); 12178afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_ParseFail; 12182f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 12196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 122086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '(' token. 12218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 12226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 12238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter const AsmToken &Tok1 = Parser.getTok(); // Get next token 12246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok1.is(AsmToken::Dollar)) { 122586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$' token. 1226ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (tryParseRegisterOperand(Operands, isMips64())) { 12276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 12286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 12296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 12306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 12316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else { 123230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 12336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 12346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 12356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 123686924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok2 = Parser.getTok(); // Get next token. 12376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok2.isNot(AsmToken::RParen)) { 12386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "')' expected"); 12396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 12406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 12416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1242ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1243ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 124486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the ')' token. 12456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 12466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (IdVal == 0) 12476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter IdVal = MCConstantExpr::Create(0, getContext()); 12486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 124986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Replace the register operand with the memory operand. 12506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 12516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter int RegNo = op->getReg(); 125286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Remove the register from the operands. 12536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.pop_back(); 125486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add the memory operand. 12558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 12568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter int64_t Imm; 12578afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (IdVal->EvaluateAsAbsolute(Imm)) 12588afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter IdVal = MCConstantExpr::Create(Imm, getContext()); 12598afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 12608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 12618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter getContext()); 12628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 12638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 12646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 12656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter delete op; 1266ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return MatchOperand_Success; 1267ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1268ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1269ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 12707231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 12717231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic int RegKind) { 12727231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1273c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().getKind() == AsmToken::Identifier) { 12747231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic if (searchSymbolAlias(Operands, Kind)) 1275c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_Success; 1276c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_NoMatch; 1277c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 127886924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$', we have an error. 1279ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1280ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1281ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1282ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1283a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka if (!tryParseRegisterOperand(Operands, 12841858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka RegKind == MipsOperand::Kind_GPR64)) { 128586924b4182537745659f2660244f3402c1e1ca4dJack Carter // Set the proper register kind. 1286ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 12877231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic op->setRegKind(Kind); 12881858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka if ((Kind == MipsOperand::Kind_GPR32) 1289764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic && (getLexer().is(AsmToken::LParen))) { 1290764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic // Check if it is indexed addressing operand. 1291764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1292764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic Parser.Lex(); // Eat the parenthesis. 1293764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic if (parseRegs(Operands,RegKind) != MatchOperand_Success) 1294764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic return MatchOperand_NoMatch; 1295764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic if (getLexer().isNot(AsmToken::RParen)) 1296764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic return MatchOperand_NoMatch; 1297764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1298764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic Parser.Lex(); 1299764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic } 1300ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 1302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1304088483627720acb58c96951b7b634f67312c7272Vladimir Medic 13057231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::OperandMatchResultTy 13061858786285139b87961d9ca08de91dcd59364afbAkira HatanakaMipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 13077231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 13087231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic if (!isMips64()) 13097231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic return MatchOperand_NoMatch; 13101858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka return parseRegs(Operands, (int) MipsOperand::Kind_GPR64); 13117231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic} 13127231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic 13137231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::OperandMatchResultTy 13141858786285139b87961d9ca08de91dcd59364afbAkira HatanakaMipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 13151858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka return parseRegs(Operands, (int) MipsOperand::Kind_GPR32); 13167231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic} 1317ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 131890b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::OperandMatchResultTy 131990b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 132090b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 132190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic if (isFP64()) 132290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return MatchOperand_NoMatch; 132390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic // Double operand is expected, set appropriate format 132490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic setFpFormat(FP_FORMAT_D); 132590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 132690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs); 132790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic} 132890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 132990b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::OperandMatchResultTy 133090b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 133190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic if (!isFP64()) 133290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return MatchOperand_NoMatch; 133390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic // Double operand is expected, set appropriate format 133490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic setFpFormat(FP_FORMAT_D); 133590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 133690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs); 133790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic} 133890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 133990b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::OperandMatchResultTy 134090b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 134190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic // Single operand is expected, set appropriate format 134290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic setFpFormat(FP_FORMAT_S); 134390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs); 134490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic} 134590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic 1346b67775df0cc702cd94408200ff2d58cf83f1334aVladimir MedicMipsAsmParser::OperandMatchResultTy 1347b67775df0cc702cd94408200ff2d58cf83f1334aVladimir MedicMipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1348b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic // If the first token is not '$' we have an error. 1349b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic if (Parser.getTok().isNot(AsmToken::Dollar)) 1350b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic return MatchOperand_NoMatch; 1351b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1352b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic SMLoc S = Parser.getTok().getLoc(); 1353b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic Parser.Lex(); // Eat the '$' 1354b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1355b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic const AsmToken &Tok = Parser.getTok(); // Get next token. 1356b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1357b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic if (Tok.isNot(AsmToken::Identifier)) 1358b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic return MatchOperand_NoMatch; 1359b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1360b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic if (!Tok.getIdentifier().startswith("fcc")) 1361b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic return MatchOperand_NoMatch; 1362b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1363b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic StringRef NumString = Tok.getIdentifier().substr(3); 1364b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1365b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic unsigned IntVal; 1366b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic if (NumString.getAsInteger(10, IntVal)) 1367b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic return MatchOperand_NoMatch; 1368b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1369b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic unsigned Reg = matchRegisterByNumber(IntVal, Mips::FCCRegClassID); 1370b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1371b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1372b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic Op->setRegKind(MipsOperand::Kind_FCCRegs); 1373b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic Operands.push_back(Op); 1374b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 1375b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic Parser.Lex(); // Eat the register number. 1376a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka return MatchOperand_Success; 1377a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka} 1378a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1379a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira HatanakaMipsAsmParser::OperandMatchResultTy 1380a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira HatanakaMipsAsmParser::parseACRegsDSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1381a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka // If the first token is not '$' we have an error. 1382a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka if (Parser.getTok().isNot(AsmToken::Dollar)) 1383a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka return MatchOperand_NoMatch; 1384a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1385a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka SMLoc S = Parser.getTok().getLoc(); 1386a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka Parser.Lex(); // Eat the '$' 1387a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1388a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka const AsmToken &Tok = Parser.getTok(); // Get next token. 1389a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1390a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka if (Tok.isNot(AsmToken::Identifier)) 1391a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka return MatchOperand_NoMatch; 1392a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1393a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka if (!Tok.getIdentifier().startswith("acc")) 1394a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka return MatchOperand_NoMatch; 1395a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1396a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka StringRef NumString = Tok.getIdentifier().substr(3); 1397a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1398a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka unsigned IntVal; 1399a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka if (NumString.getAsInteger(10, IntVal)) 1400a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka return MatchOperand_NoMatch; 1401a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1402a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka unsigned Reg = matchRegisterByNumber(IntVal, Mips::ACRegsDSPRegClassID); 1403a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1404a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1405a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka Op->setRegKind(MipsOperand::Kind_ACRegsDSP); 1406a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka Operands.push_back(Op); 1407a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka 1408a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka Parser.Lex(); // Eat the register number. 1409b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic return MatchOperand_Success; 1410b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic} 1411b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic 141286924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::searchSymbolAlias( 14137231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) { 1414c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1415c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1416c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Sym) { 1417c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter SMLoc S = Parser.getTok().getLoc(); 1418c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCExpr *Expr; 1419c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Sym->isVariable()) 1420c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Expr = Sym->getVariableValue(); 1421c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter else 1422c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1423c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Expr->getKind() == MCExpr::SymbolRef) { 14247231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind; 1425c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1426c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const StringRef DefSymbol = Ref->getSymbol().getName(); 1427c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (DefSymbol.startswith("$")) { 1428c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter int RegNum = -1; 1429c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter APInt IntVal(32, -1); 1430c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) 1431c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter RegNum = matchRegisterByNumber(IntVal.getZExtValue(), 1432088483627720acb58c96951b7b634f67312c7272Vladimir Medic isMips64() 14331858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka ? Mips::GPR64RegClassID 14341858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka : Mips::GPR32RegClassID); 14357231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic else { 14367231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic // Lookup for the register with the corresponding name. 14377231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic switch (Kind) { 14387231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic case MipsOperand::Kind_AFGR64Regs: 14397231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic case MipsOperand::Kind_FGR64Regs: 14407231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_D); 14417231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic break; 14427231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic case MipsOperand::Kind_FGR32Regs: 14437231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S); 14447231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic break; 14451858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka case MipsOperand::Kind_GPR64: 14461858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka case MipsOperand::Kind_GPR32: 14477231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic default: 14487231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); 14497231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic break; 14507231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic } 14517231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic } 1452c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (RegNum > -1) { 1453c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.Lex(); 145486924b4182537745659f2660244f3402c1e1ca4dJack Carter MipsOperand *op = MipsOperand::CreateReg(RegNum, S, 145586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 14567231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic op->setRegKind(Kind); 1457c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Operands.push_back(op); 1458c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return true; 1459c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1460c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1461c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } else if (Expr->getKind() == MCExpr::Constant) { 1462c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.Lex(); 1463c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 146486924b4182537745659f2660244f3402c1e1ca4dJack Carter MipsOperand *op = MipsOperand::CreateImm(Const, S, 1465088483627720acb58c96951b7b634f67312c7272Vladimir Medic Parser.getTok().getLoc()); 1466c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Operands.push_back(op); 1467c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return true; 1468c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1469c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1470c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1471c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter} 147286924b4182537745659f2660244f3402c1e1ca4dJack Carter 1473ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1474ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1475ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 147686924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$' we have error. 1477ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1478ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1479ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 148086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$'. 1481ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 148286924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get the next token. 1483ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.isNot(AsmToken::Integer)) 1484ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1485ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1486ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum = Tok.getIntVal(); 148786924b4182537745659f2660244f3402c1e1ca4dJack Carter // At the moment only hwreg29 is supported. 1488ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 29) 1489ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1490ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1491ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 149286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 1493ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_HWRegs); 1494ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1495ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 149686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the register number. 1497ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1498ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1499ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1500ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 150186924b4182537745659f2660244f3402c1e1ca4dJack CarterMipsAsmParser::parseHW64Regs( 150286924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1503c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter 1504c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter if (!isMips64()) 1505c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter return MatchOperand_NoMatch; 150686924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$' we have an error. 1507ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1508ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1509ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 1510ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1511ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 151286924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get the next token. 1513ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.isNot(AsmToken::Integer)) 1514ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1515ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1516ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum = Tok.getIntVal(); 151786924b4182537745659f2660244f3402c1e1ca4dJack Carter // At the moment only hwreg29 is supported. 1518ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 29) 1519ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1520ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1521ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 152286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 1523c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter op->setRegKind(MipsOperand::Kind_HW64Regs); 1524ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1525ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 152686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the register number. 1527ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1528ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1529ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1530ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1531ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 153286924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$' we have an error. 1533ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 153494ce6dadd131ca80adf2ba05391f689684540601Akira Hatanaka return MatchOperand_NoMatch; 15359a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka 1536ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 153786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$' 1538ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 153986924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get next token. 1540ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 15419a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka if (Tok.isNot(AsmToken::Integer)) 154294ce6dadd131ca80adf2ba05391f689684540601Akira Hatanaka return MatchOperand_NoMatch; 15439a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka 15449a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka unsigned Reg = matchRegisterByNumber(Tok.getIntVal(), Mips::CCRRegClassID); 15459a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka 15469a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 15479a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka Op->setRegKind(MipsOperand::Kind_CCRRegs); 15489a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka Operands.push_back(Op); 1549ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 155086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the register number. 1551ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1552ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1553ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 15546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 15556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 15566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind VK 15576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 15586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 15596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 15606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 15616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 15626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 15636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 15646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 15656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 15666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 15676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 15686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 15696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 15706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 15716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 15726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 15736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 15746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 15756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Default(MCSymbolRefExpr::VK_None); 15766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 15776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return VK; 15786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 1579f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1580fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 15816a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1582fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1583fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic // Check if we have valid mnemonic 1584f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper if (!mnemonicIsValid(Name, 0)) { 1585fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic Parser.eatToEndOfStatement(); 1586fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic return Error(NameLoc, "Unknown instruction"); 1587fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic } 1588088483627720acb58c96951b7b634f67312c7272Vladimir Medic // First operand in MCInst is instruction mnemonic. 1589088483627720acb58c96951b7b634f67312c7272Vladimir Medic Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1590ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1591ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the remaining operands. 1592ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1593ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the first operand. 1594088483627720acb58c96951b7b634f67312c7272Vladimir Medic if (ParseOperand(Operands, Name)) { 1595ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1596cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1597ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1598ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1599ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 160086924b4182537745659f2660244f3402c1e1ca4dJack Carter while (getLexer().is(AsmToken::Comma)) { 160186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the comma. 1602ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Parse and remember the operand. 1603ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ParseOperand(Operands, Name)) { 1604ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1605cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1606ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1607ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1608ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1609ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1610ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1611ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1612cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1613ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1614ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 161586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 1616ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 1617fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1618fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 161930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 162086924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc Loc = getLexer().getLoc(); 162186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.eatToEndOfStatement(); 162286924b4182537745659f2660244f3402c1e1ca4dJack Carter return Error(Loc, ErrorMsg); 162330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 162430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 162530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() { 162686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Line should look like: ".set noat". 162786924b4182537745659f2660244f3402c1e1ca4dJack Carter // set at reg to 0. 162810d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(0); 162930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // eat noat 163030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 163186924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 163230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 163330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 163430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 163530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 163686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 163730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 163830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 163986924b4182537745659f2660244f3402c1e1ca4dJack Carter 164030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() { 164186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Line can be .set at - defaults to $1 164230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // or .set at=$reg 164399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int AtRegNo; 164430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter getParser().Lex(); 164530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().is(AsmToken::EndOfStatement)) { 164610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(1); 164786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 164830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 164930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (getLexer().is(AsmToken::Equal)) { 165086924b4182537745659f2660244f3402c1e1ca4dJack Carter getParser().Lex(); // Eat the '='. 165130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::Dollar)) { 165230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 165330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 165430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 165586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$'. 165699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter const AsmToken &Reg = Parser.getTok(); 165799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (Reg.is(AsmToken::Identifier)) { 165899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 165999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else if (Reg.is(AsmToken::Integer)) { 166099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = Reg.getIntVal(); 166199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else { 166230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 166330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 166430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 166599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 166686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (AtRegNo < 1 || AtRegNo > 31) { 166799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter reportParseError("unexpected token in statement"); 166899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return false; 166999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } 167099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 167199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (!Options.setATReg(AtRegNo)) { 167230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 167330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 167430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 167586924b4182537745659f2660244f3402c1e1ca4dJack Carter getParser().Lex(); // Eat the register. 167630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 167730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 167830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 167930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 168086924b4182537745659f2660244f3402c1e1ca4dJack Carter } 168186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 168230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 168330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else { 168430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 168530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 168630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 168730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 168830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 168930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() { 169030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 169186924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 169230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 169330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 169430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 169530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 169610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setReorder(); 169786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 169830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 169930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 170030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 170130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() { 170286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); 170386924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 170486924b4182537745659f2660244f3402c1e1ca4dJack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 170586924b4182537745659f2660244f3402c1e1ca4dJack Carter reportParseError("unexpected token in statement"); 170630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 170786924b4182537745659f2660244f3402c1e1ca4dJack Carter } 170886924b4182537745659f2660244f3402c1e1ca4dJack Carter Options.setNoreorder(); 170986924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 171086924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 171130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 171230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 171330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() { 171430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 171586924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 171630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 171730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 171830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 171930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 172010d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setMacro(); 172186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 172230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 172330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 172430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 172530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() { 172630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 172786924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 172830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 172930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 173030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 173130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 173210d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter if (Options.isReorder()) { 173330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 173430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 173530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 173610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setNomacro(); 173786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 173830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 173930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 1740c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1741c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() { 1742c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter StringRef Name; 1743c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCExpr *Value; 1744c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1745c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Parser.parseIdentifier(Name)) 1746c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter reportParseError("expected identifier after .set"); 1747c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1748c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().isNot(AsmToken::Comma)) 1749c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("unexpected token in .set directive"); 17508afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Lex(); // Eat comma 1751c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1752c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter if (getLexer().is(AsmToken::Dollar)) { 1753c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter MCSymbol *Symbol; 1754c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter SMLoc DollarLoc = getLexer().getLoc(); 1755c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter // Consume the dollar sign, and check for a following identifier. 1756c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter Parser.Lex(); 1757c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter // We have a '$' followed by something, make sure they are adjacent. 1758c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1759c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter return true; 1760c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter StringRef Res = StringRef(DollarLoc.getPointer(), 1761c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); 1762c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter Symbol = getContext().GetOrCreateSymbol(Res); 1763c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter Parser.Lex(); 1764c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 1765c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter getContext()); 1766c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter } else if (Parser.parseExpression(Value)) 1767c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter return reportParseError("expected valid expression after comma"); 1768c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 176986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check if the Name already exists as a symbol. 1770c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MCSymbol *Sym = getContext().LookupSymbol(Name); 177186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Sym) 1772c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("symbol already defined"); 1773c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym = getContext().GetOrCreateSymbol(Name); 1774c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym->setVariableValue(Value); 1775c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1776c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1777c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter} 177886924b4182537745659f2660244f3402c1e1ca4dJack Carter 177930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() { 178030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 178186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Get the next token. 178230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter const AsmToken &Tok = Parser.getTok(); 178330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 178430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Tok.getString() == "noat") { 178530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoAtDirective(); 178630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "at") { 178730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetAtDirective(); 178830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "reorder") { 178930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetReorderDirective(); 179030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "noreorder") { 179130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoReorderDirective(); 179230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "macro") { 179330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetMacroDirective(); 179430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomacro") { 179530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoMacroDirective(); 179630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomips16") { 179786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1798cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 179930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 180030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomicromips") { 180186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1802cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 180330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 1804c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } else { 180586924b4182537745659f2660244f3402c1e1ca4dJack Carter // It is just an identifier, look for an assignment. 1806c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter parseSetAssignment(); 1807c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 180830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 1809801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 181030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 181130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 181230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1813801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// parseDirectiveWord 1814801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// ::= .word [ expression (, expression)* ] 1815801c5838830d190a6b0d8e462bd43805f66ba50fJack Carterbool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1816801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1817801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter for (;;) { 1818801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter const MCExpr *Value; 1819cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Value)) 1820801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return true; 1821801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1822801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter getParser().getStreamer().EmitValue(Value, Size); 1823801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1824801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().is(AsmToken::EndOfStatement)) 1825801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter break; 1826801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1827801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter // FIXME: Improve diagnostic. 1828801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::Comma)) 1829801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return Error(L, "unexpected token in directive"); 1830801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 1831801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1832801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1833801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1834801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 1835801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 1836801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter} 1837801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 183830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1839acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1840801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter StringRef IDVal = DirectiveID.getString(); 1841801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 184286924b4182537745659f2660244f3402c1e1ca4dJack Carter if (IDVal == ".ent") { 184386924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1844acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 1845acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1846acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1847acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1848801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".end") { 184986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1850acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 1851acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1852acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1853acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1854801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".frame") { 185586924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1856cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1857acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1858acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1859acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1860801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".set") { 186130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseDirectiveSet(); 1862acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1863acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1864801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".fmask") { 186586924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1866cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1867acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1868acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1869acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1870801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".mask") { 187186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1872cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1873acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1874acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1875acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1876801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".gpword") { 187786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1878cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1879acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1880acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1881acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1882801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".word") { 1883801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter parseDirectiveWord(4, DirectiveID.getLoc()); 1884801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 1885801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1886801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1887fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 1888fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1889fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 1890fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() { 1891fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1892fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1893fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1894fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1895fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1896ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1897ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER 1898ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION 1899ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc" 1900