MipsAsmParser.cpp revision 86924b4182537745659f2660244f3402c1e1ca4d
1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 3fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// The LLVM Compiler Infrastructure 4fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 5fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// This file is distributed under the University of Illinois Open Source 6fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// License. See LICENSE.TXT for details. 7fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// 8fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//===----------------------------------------------------------------------===// 9fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 10fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h" 11ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h" 12ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/ADT/StringSwitch.h" 13ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h" 14ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h" 15ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h" 19ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h" 20ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h" 2172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCTargetAsmParser.h" 22ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/Support/TargetRegistry.h" 23fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 24fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm; 25fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 26fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace { 2730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions { 2830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic: 2930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter MipsAssemblerOptions(): 3030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter aTReg(1), reorder(true), macro(true) { 3130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 3230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 3330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter unsigned getATRegNum() {return aTReg;} 3430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool setATReg(unsigned Reg); 35ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 3630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool isReorder() {return reorder;} 3730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setReorder() {reorder = true;} 3830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setNoreorder() {reorder = false;} 3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool isMacro() {return macro;} 4130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setMacro() {macro = true;} 4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter void setNomacro() {macro = false;} 4330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate: 4530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter unsigned aTReg; 4630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool reorder; 4730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool macro; 4830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}; 4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 5030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 5130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace { 52fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser { 5372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 54f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter enum FpFormatTy { 55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_NONE = -1, 56f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_S, 57f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_D, 58f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_L, 59f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FP_FORMAT_W 60f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } FpFormat; 61f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 62ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCSubtargetInfo &STI; 63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &Parser; 6410d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter MipsAssemblerOptions Options; 6530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 6672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER 6772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc" 6872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 6984125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 70fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 7184125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 7284125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm); 73fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 74fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 75fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 766a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 776a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier SMLoc NameLoc, 7872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka SmallVectorImpl<MCParsedAsmOperand*> &Operands); 79fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 80f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool parseMathOperation(StringRef Name, SMLoc NameLoc, 81f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands); 82f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 83fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola bool ParseDirective(AsmToken DirectiveID); 84fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 85ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsAsmParser::OperandMatchResultTy 86ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 87ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 88ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 89ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 90ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 91ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 92ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 93ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 94ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 95ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 96ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 97ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 98ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 99ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsAsmParser::OperandMatchResultTy 101ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 102038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 103c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 104c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter unsigned RegisterClass); 105c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 106ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 107ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic); 108ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 109ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int tryParseRegister(bool is64BitReg); 110ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 111ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 112ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool is64BitReg); 113ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1149d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter bool needsExpansion(MCInst &Inst); 1159d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 1169d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter void expandInstruction(MCInst &Inst, SMLoc IDLoc, 1172490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 1189d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 1192490dc650895149423bb59538dc03ca352222702Jack Carter SmallVectorImpl<MCInst> &Instructions); 1202f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1212f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 1222f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter SmallVectorImpl<MCInst> &Instructions); 12425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter void expandMemInst(MCInst &Inst, SMLoc IDLoc, 12525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions, 12625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool isLoad,bool isImmOpnd); 12730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool reportParseError(StringRef ErrorMsg); 12830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 130ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool parseRelocOperand(const MCExpr *&Res); 13130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 1338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 1348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool isEvaluated(const MCExpr *Expr); 13530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseDirectiveSet(); 13630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 13730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetAtDirective(); 13830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoAtDirective(); 13930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetMacroDirective(); 14030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoMacroDirective(); 14130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetReorderDirective(); 14230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter bool parseSetNoReorderDirective(); 14330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 144c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter bool parseSetAssignment(); 145c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 146801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter bool parseDirectiveWord(unsigned Size, SMLoc L); 147801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 149f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 150ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter bool isMips64() const { 151ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 152ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 153ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 154f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool isFP64() const { 155f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 156f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 157f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 158ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int matchRegisterName(StringRef Symbol, bool is64BitReg); 159ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 16099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int matchCPURegisterName(StringRef Symbol); 16199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 162ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 163ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 164f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(FpFormatTy Format) { 165f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = Format; 166f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 167f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 168f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setDefaultFpFormat(); 169f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 170f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter void setFpFormat(StringRef Format); 171f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormatTy getFpFormat() {return FpFormat;} 173f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 174f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool requestsDoubleOperand(StringRef Mnemonic); 175f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 17686924b4182537745659f2660244f3402c1e1ca4dJack Carter unsigned getReg(int RC, int RegNo); 177038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier 17899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int getATReg(); 17925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 18025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter bool processInstruction(MCInst &Inst, SMLoc IDLoc, 18125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVectorImpl<MCInst> &Instructions); 182fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic: 183fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 184ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter : MCTargetAsmParser(), STI(sti), Parser(parser) { 185ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Initialize the set of available features. 186ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 187fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola } 188fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 189ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmParser &getParser() const { return Parser; } 190ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCAsmLexer &getLexer() const { return Parser.getLexer(); } 191ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 192fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}; 193fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 194fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 19572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace { 19672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 19772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine 19872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction. 19972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand { 200ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 201ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic: 202ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter enum RegisterKind { 203ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_None, 204ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_CPURegs, 205ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_CPU64Regs, 206ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_HWRegs, 207ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_HW64Regs, 208ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_FGR32Regs, 209ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_FGR64Regs, 21099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter Kind_AFGR64Regs, 211ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Kind_CCRRegs 212ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter }; 213ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 214ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate: 21572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka enum KindTy { 21672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CondCode, 21772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_CoprocNum, 21872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Immediate, 21972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Memory, 22072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_PostIndexRegister, 22172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Register, 22272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka k_Token 22372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } Kind; 22472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 22572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 226ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 227a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token { 228a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const char *Data; 229a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Length; 230a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 231a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 232a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp { 233a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned RegNum; 234a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher RegisterKind Kind; 235a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 236a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 237a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp { 238a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Val; 239a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 240a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 241a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp { 242a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher unsigned Base; 243a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher const MCExpr *Off; 244a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher }; 245a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher 246ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter union { 247a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct Token Tok; 248a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct RegOp Reg; 249a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct ImmOp Imm; 250a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher struct MemOp Mem; 251ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter }; 252ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 253ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc StartLoc, EndLoc; 254ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 25572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic: 25672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addRegOperands(MCInst &Inst, unsigned N) const { 257ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 258ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateReg(getReg())); 25972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 260ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 26172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 262ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Add as immediate when possible. Null MCExpr = 0. 263ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Expr == 0) 264ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(0)); 265ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 266ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 267ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter else 268ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Inst.addOperand(MCOperand::CreateExpr(Expr)); 26972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 270ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 27172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addImmOperands(MCInst &Inst, unsigned N) const { 272ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert(N == 1 && "Invalid number of operands!"); 273ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *Expr = getImm(); 27486924b4182537745659f2660244f3402c1e1ca4dJack Carter addExpr(Inst, Expr); 27572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 276ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 27772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka void addMemOperands(MCInst &Inst, unsigned N) const { 2786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert(N == 2 && "Invalid number of operands!"); 2796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 2806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Inst.addOperand(MCOperand::CreateReg(getMemBase())); 2816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 2826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Expr = getMemOff(); 28386924b4182537745659f2660244f3402c1e1ca4dJack Carter addExpr(Inst, Expr); 28472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 28572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 28672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isReg() const { return Kind == k_Register; } 28772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isImm() const { return Kind == k_Immediate; } 28872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isToken() const { return Kind == k_Token; } 28972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka bool isMem() const { return Kind == k_Memory; } 29072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 29172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka StringRef getToken() const { 29272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert(Kind == k_Token && "Invalid access!"); 293ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return StringRef(Tok.Data, Tok.Length); 29472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 29572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 29672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka unsigned getReg() const { 29772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka assert((Kind == k_Register) && "Invalid access!"); 298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Reg.RegNum; 299ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 300ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void setRegKind(RegisterKind RegKind) { 302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Reg.Kind = RegKind; 304ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 305ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 306ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *getImm() const { 307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter assert((Kind == k_Immediate) && "Invalid access!"); 308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Imm.Val; 309ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 310ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 3116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter unsigned getMemBase() const { 3126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 3136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Base; 3146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 3166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *getMemOff() const { 3176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter assert((Kind == k_Memory) && "Invalid access!"); 3186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Mem.Off; 3196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 321ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 322ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Token); 323ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Data = Str.data(); 324ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Tok.Length = Str.size(); 325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = S; 327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 330ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 331ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Register); 332ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Reg.RegNum = RegNum; 333ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 334ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 335ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 336ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 337ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 338ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 339ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MipsOperand *Op = new MipsOperand(k_Immediate); 340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->Imm.Val = Val; 341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->StartLoc = S; 342ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Op->EndLoc = E; 343ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Op; 34472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 34572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 3466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 3476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter SMLoc S, SMLoc E) { 3486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand *Op = new MipsOperand(k_Memory); 3496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Base = Base; 3506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->Mem.Off = Off; 3516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->StartLoc = S; 3526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Op->EndLoc = E; 3536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return Op; 3546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 3556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 356ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isCPURegsAsm() const { 357a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi return Kind == k_Register && Reg.Kind == Kind_CPURegs; 358ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 359ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const { 360ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 361ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 362ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 363ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isCPU64RegsAsm() const { 364a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi return Kind == k_Register && Reg.Kind == Kind_CPU64Regs; 365ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 366ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const { 367ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 368ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 369ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 370ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isHWRegsAsm() const { 371ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 372ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_HWRegs; 373ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 374ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const { 375ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 376ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 377ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 378ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isHW64RegsAsm() const { 379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_HW64Regs; 381ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 382ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const { 383ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 385ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 386ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter void addCCRAsmOperands(MCInst &Inst, unsigned N) const { 387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 388ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter bool isCCRAsm() const { 391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter assert((Kind == k_Register) && "Invalid access!"); 392ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return Reg.Kind == Kind_CCRRegs; 393ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 394ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 395ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getStartLoc - Get the location of the first token of this operand. 39686924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc getStartLoc() const { 39786924b4182537745659f2660244f3402c1e1ca4dJack Carter return StartLoc; 39886924b4182537745659f2660244f3402c1e1ca4dJack Carter } 399ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter /// getEndLoc - Get the location of the last token of this operand. 40086924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc getEndLoc() const { 40186924b4182537745659f2660244f3402c1e1ca4dJack Carter return EndLoc; 40286924b4182537745659f2660244f3402c1e1ca4dJack Carter } 403ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 40472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka virtual void print(raw_ostream &OS) const { 40572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka llvm_unreachable("unimplemented!"); 40672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka } 40786924b4182537745659f2660244f3402c1e1ca4dJack Carter}; // class MipsOperand 40886924b4182537745659f2660244f3402c1e1ca4dJack Carter} // namespace 40972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka 41025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm { 41125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[]; 41225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 41325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) { 41425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return MipsInsts[Opcode]; 41525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 41625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 41725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 4188afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter SmallVectorImpl<MCInst> &Instructions) { 41925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 42025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Inst.setLoc(IDLoc); 42125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MCID.mayLoad() || MCID.mayStore()) { 42225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // Check the offset of memory operand, if it is a symbol 42386924b4182537745659f2660244f3402c1e1ca4dJack Carter // reference or immediate we may have to expand instructions. 42486924b4182537745659f2660244f3402c1e1ca4dJack Carter for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 42525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 42686924b4182537745659f2660244f3402c1e1ca4dJack Carter if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) 42786924b4182537745659f2660244f3402c1e1ca4dJack Carter || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 42825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCOperand &Op = Inst.getOperand(i); 42925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (Op.isImm()) { 43025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter int MemOffset = Op.getImm(); 43125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (MemOffset < -32768 || MemOffset > 32767) { 43286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Offset can't exceed 16bit value. 43386924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 43425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 43525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 43625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } else if (Op.isExpr()) { 43725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *Expr = Op.getExpr(); 43886924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Expr->getKind() == MCExpr::SymbolRef) { 43925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR = 4408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter static_cast<const MCSymbolRefExpr*>(Expr); 44125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (SR->getKind() == MCSymbolRefExpr::VK_None) { 44286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Expand symbol. 44386924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 44425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 44525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 4468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else if (!isEvaluated(Expr)) { 44786924b4182537745659f2660244f3402c1e1ca4dJack Carter expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 4488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 44925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 45025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 45125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 45286924b4182537745659f2660244f3402c1e1ca4dJack Carter } // for 45386924b4182537745659f2660244f3402c1e1ca4dJack Carter } // if load/store 45425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 45525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (needsExpansion(Inst)) 45625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter expandInstruction(Inst, IDLoc, Instructions); 45725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else 45825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(Inst); 45925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 46025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return false; 46125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 46225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 4639d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) { 4649d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 46586924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (Inst.getOpcode()) { 46686924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadImm32Reg: 46786924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Imm: 46886924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Reg: 46986924b4182537745659f2660244f3402c1e1ca4dJack Carter return true; 47086924b4182537745659f2660244f3402c1e1ca4dJack Carter default: 47186924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 4729d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 4739d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 4742490dc650895149423bb59538dc03ca352222702Jack Carter 4759d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 47686924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 47786924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (Inst.getOpcode()) { 47886924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadImm32Reg: 47986924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadImm(Inst, IDLoc, Instructions); 48086924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Imm: 48186924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadAddressImm(Inst, IDLoc, Instructions); 48286924b4182537745659f2660244f3402c1e1ca4dJack Carter case Mips::LoadAddr32Reg: 48386924b4182537745659f2660244f3402c1e1ca4dJack Carter return expandLoadAddressReg(Inst, IDLoc, Instructions); 48486924b4182537745659f2660244f3402c1e1ca4dJack Carter } 4859d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 4862490dc650895149423bb59538dc03ca352222702Jack Carter 4879d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 48886924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 4892490dc650895149423bb59538dc03ca352222702Jack Carter MCInst tmpInst; 4909d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &ImmOp = Inst.getOperand(1); 4912f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 4929d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter const MCOperand &RegOp = Inst.getOperand(0); 4939d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter assert(RegOp.isReg() && "expected register operand kind"); 4949d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter 4959d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter int ImmValue = ImmOp.getImm(); 4962490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.setLoc(IDLoc); 49786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (0 <= ImmValue && ImmValue <= 65535) { 49886924b4182537745659f2660244f3402c1e1ca4dJack Carter // For 0 <= j <= 65535. 4999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => ori d,$zero,j 500ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5012490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 50286924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 5032490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5049d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 50586924b4182537745659f2660244f3402c1e1ca4dJack Carter } else if (ImmValue < 0 && ImmValue >= -32768) { 50686924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j < 0. 5079d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => addiu d,$zero,j 508ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5092490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 51086924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 5112490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5129d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5139d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } else { 51486924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 5159d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // li d,j => lui d,hi16(j) 5162f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter // ori d,d,lo16(j) 517ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5182490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5192490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 5209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5212490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.clear(); 522ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5232490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5242490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 5252490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 5262490dc650895149423bb59538dc03ca352222702Jack Carter tmpInst.setLoc(IDLoc); 5279d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter Instructions.push_back(tmpInst); 5289d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter } 5299d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter} 5302490dc650895149423bb59538dc03ca352222702Jack Carter 5312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 53286924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 5332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 5342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(2); 5352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 5362f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &SrcRegOp = Inst.getOperand(1); 5372f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(SrcRegOp.isReg() && "expected register operand kind"); 5382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &DstRegOp = Inst.getOperand(0); 5392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(DstRegOp.isReg() && "expected register operand kind"); 5402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 54186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (-32768 <= ImmValue && ImmValue <= 65535) { 54286924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j <= 65535. 54386924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j(s) => addiu d,s,j 544ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5452f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5462f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 5472f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5482f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5492f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 55086924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 55186924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j(s) => lui d,hi16(j) 55286924b4182537745659f2660244f3402c1e1ca4dJack Carter // ori d,d,lo16(j) 55386924b4182537745659f2660244f3402c1e1ca4dJack Carter // addu d,d,s 554ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5552f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5562f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 5572f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5582f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 559ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::ORi); 5602f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5612f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5622f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 5632f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5642f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.clear(); 5652f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDu); 5662f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5672f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 5682f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 5692f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5702f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 5712f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 5722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 5732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 57486924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions) { 5752f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter MCInst tmpInst; 5762f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &ImmOp = Inst.getOperand(1); 5772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(ImmOp.isImm() && "expected immediate operand kind"); 5782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter const MCOperand &RegOp = Inst.getOperand(0); 5792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter assert(RegOp.isReg() && "expected register operand kind"); 5802f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter int ImmValue = ImmOp.getImm(); 58186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (-32768 <= ImmValue && ImmValue <= 65535) { 58286924b4182537745659f2660244f3402c1e1ca4dJack Carter // For -32768 <= j <= 65535. 58386924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j => addiu d,$zero,j 5842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.setOpcode(Mips::ADDiu); 5852f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 58686924b4182537745659f2660244f3402c1e1ca4dJack Carter tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 5872f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 5882f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 5892f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } else { 59086924b4182537745659f2660244f3402c1e1ca4dJack Carter // For any other value of j that is representable as a 32-bit integer. 59186924b4182537745659f2660244f3402c1e1ca4dJack Carter // la d,j => lui d,hi16(j) 59286924b4182537745659f2660244f3402c1e1ca4dJack Carter // ori d,d,lo16(j) 593ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter tmpInst.setOpcode(Mips::LUi); 5942f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.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(RegOp.getReg())); 6002f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 6012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 6022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter Instructions.push_back(tmpInst); 6032f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 6042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter} 6052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter 60625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 60786924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) { 60825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCSymbolRefExpr *SR; 60925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter MCInst TempInst; 61086924b4182537745659f2660244f3402c1e1ca4dJack Carter unsigned ImmOffset, HiOffset, LoOffset; 61125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter const MCExpr *ExprOffset; 61225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned TmpRegNum; 61386924b4182537745659f2660244f3402c1e1ca4dJack Carter unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID 61486924b4182537745659f2660244f3402c1e1ca4dJack Carter : Mips::CPURegsRegClassID, getATReg()); 61586924b4182537745659f2660244f3402c1e1ca4dJack Carter // 1st operand is either the source or destination register. 61625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 61725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned RegOpNum = Inst.getOperand(0).getReg(); 61886924b4182537745659f2660244f3402c1e1ca4dJack Carter // 2nd operand is the base register. 61925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 62025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter unsigned BaseRegNum = Inst.getOperand(1).getReg(); 62186924b4182537745659f2660244f3402c1e1ca4dJack Carter // 3rd operand is either an immediate or expression. 62225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) { 62325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 62425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ImmOffset = Inst.getOperand(2).getImm(); 62525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter LoOffset = ImmOffset & 0x0000ffff; 62625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset = (ImmOffset & 0xffff0000) >> 16; 62786924b4182537745659f2660244f3402c1e1ca4dJack Carter // If msb of LoOffset is 1(negative number) we must increment HiOffset. 62825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (LoOffset & 0x8000) 62925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter HiOffset++; 63086924b4182537745659f2660244f3402c1e1ca4dJack Carter } else 63125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter ExprOffset = Inst.getOperand(2).getExpr(); 63286924b4182537745659f2660244f3402c1e1ca4dJack Carter // All instructions will have the same location. 63325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setLoc(IDLoc); 63425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // 1st instruction in expansion is LUi. For load instruction we can use 63525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter // the dst register as a temporary if base and dst are different, 63686924b4182537745659f2660244f3402c1e1ca4dJack Carter // but for stores we must use $at. 63786924b4182537745659f2660244f3402c1e1ca4dJack Carter TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 63825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::LUi); 63925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 64025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 64125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 64225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 64325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 64425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SR = static_cast<const MCSymbolRefExpr*>(ExprOffset); 64586924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 64686924b4182537745659f2660244f3402c1e1ca4dJack Carter SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 64786924b4182537745659f2660244f3402c1e1ca4dJack Carter getContext()); 64825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 6498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else { 65086924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 6518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 65225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 65325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 65486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add the instruction to the list. 65525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 65686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Prepare TempInst for next instruction. 65725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 65886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add temp register to base. 65925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Mips::ADDu); 66025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 66125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 66225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 66325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 66425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 6658afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter // And finaly, create original instruction with low part 66686924b4182537745659f2660244f3402c1e1ca4dJack Carter // of offset and new base. 66725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.setOpcode(Inst.getOpcode()); 66825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 66925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 67025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (isImmOpnd) 67125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 67225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter else { 67325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter if (ExprOffset->getKind() == MCExpr::SymbolRef) { 67486924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 67586924b4182537745659f2660244f3402c1e1ca4dJack Carter SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 67686924b4182537745659f2660244f3402c1e1ca4dJack Carter getContext()); 67725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 6788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else { 67986924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 6808afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 68125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 68225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter } 68325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Instructions.push_back(TempInst); 68425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter TempInst.clear(); 68525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter} 68625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter 687fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 68884125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 689fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands, 69084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MCStreamer &Out, unsigned &ErrorInfo, 69184125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier bool MatchingInlineAsm) { 692ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter MCInst Inst; 69325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter SmallVector<MCInst, 8> Instructions; 6946e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 69584125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier MatchingInlineAsm); 696ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 697ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (MatchResult) { 69886924b4182537745659f2660244f3402c1e1ca4dJack Carter default: 69986924b4182537745659f2660244f3402c1e1ca4dJack Carter break; 700ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_Success: { 70186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (processInstruction(Inst, IDLoc, Instructions)) 70225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter return true; 70386924b4182537745659f2660244f3402c1e1ca4dJack Carter for (unsigned i = 0; i < Instructions.size(); i++) 70425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter Out.EmitInstruction(Instructions[i]); 705ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 706ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 707ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MissingFeature: 708ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 709ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 710ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_InvalidOperand: { 711ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc ErrorLoc = IDLoc; 712ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo != ~0U) { 713ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ErrorInfo >= Operands.size()) 714ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "too few operands for instruction"); 715ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 71686924b4182537745659f2660244f3402c1e1ca4dJack Carter ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc(); 71786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (ErrorLoc == SMLoc()) 71886924b4182537745659f2660244f3402c1e1ca4dJack Carter ErrorLoc = IDLoc; 719ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 720ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 721ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(ErrorLoc, "invalid operand for instruction"); 722ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 723ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case Match_MnemonicFail: 724ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(IDLoc, "invalid instruction"); 725ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 726fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 727fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 728fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 72999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) { 730572e1bd109518f80b54d229de10699c4603944c3David Chisnall int CC; 73199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 73299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (Name == "at") 73399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return getATReg(); 73499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 735572e1bd109518f80b54d229de10699c4603944c3David Chisnall CC = StringSwitch<unsigned>(Name) 73699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("zero", 0) 73799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a0", 4) 73899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a1", 5) 73999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a2", 6) 74099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a3", 7) 74199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("v0", 2) 74299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("v1", 3) 74399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s0", 16) 74499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s1", 17) 74599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s2", 18) 74699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s3", 19) 74799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s4", 20) 74899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s5", 21) 74999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s6", 22) 75099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s7", 23) 75199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("k0", 26) 75299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("k1", 27) 75399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("sp", 29) 75499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("fp", 30) 75599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("gp", 28) 75699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("ra", 31) 75799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t0", 8) 75899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t1", 9) 75999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t2", 10) 76099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t3", 11) 76199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t4", 12) 76299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t5", 13) 76399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t6", 14) 76499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t7", 15) 76599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t8", 24) 76699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("t9", 25) 76799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Default(-1); 76899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 76986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Although SGI documentation just cuts out t0-t3 for n32/n64, 77099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 77199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 77286924b4182537745659f2660244f3402c1e1ca4dJack Carter if (isMips64() && 8 <= CC && CC <= 11) 77399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter CC += 4; 77499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 77599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (CC == -1 && isMips64()) 776572e1bd109518f80b54d229de10699c4603944c3David Chisnall CC = StringSwitch<unsigned>(Name) 77799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a4", 8) 77899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a5", 9) 77999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a6", 10) 78099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("a7", 11) 78199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("kt0", 26) 78299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("kt1", 27) 78399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter .Case("s8", 30) 784572e1bd109518f80b54d229de10699c4603944c3David Chisnall .Default(-1); 785572e1bd109518f80b54d229de10699c4603944c3David Chisnall 78699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return CC; 78799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter} 78886924b4182537745659f2660244f3402c1e1ca4dJack Carter 78999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 79099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 791b8145e3881872fffbac15693c94536446f060330Jack Carter if (Name.equals("fcc0")) 792b8145e3881872fffbac15693c94536446f060330Jack Carter return Mips::FCC0; 793b8145e3881872fffbac15693c94536446f060330Jack Carter 79499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int CC; 79599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter CC = matchCPURegisterName(Name); 796572e1bd109518f80b54d229de10699c4603944c3David Chisnall if (CC != -1) 79786924b4182537745659f2660244f3402c1e1ca4dJack Carter return matchRegisterByNumber(CC, is64BitReg ? Mips::CPU64RegsRegClassID 79886924b4182537745659f2660244f3402c1e1ca4dJack Carter : Mips::CPURegsRegClassID); 799ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 800f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Name[0] == 'f') { 801f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef NumString = Name.substr(1); 802f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter unsigned IntVal; 80386924b4182537745659f2660244f3402c1e1ca4dJack Carter if (NumString.getAsInteger(10, IntVal)) 80486924b4182537745659f2660244f3402c1e1ca4dJack Carter return -1; // This is not an integer. 805f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (IntVal > 31) 806f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 807f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 808f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormatTy Format = getFpFormat(); 809f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 810f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 811f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR32RegClassID, IntVal); 812f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Format == FP_FORMAT_D) { 81386924b4182537745659f2660244f3402c1e1ca4dJack Carter if (isFP64()) { 814f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return getReg(Mips::FGR64RegClassID, IntVal); 815f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 81686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Only even numbers available as register pairs. 81786924b4182537745659f2660244f3402c1e1ca4dJack Carter if ((IntVal > 31) || (IntVal % 2 != 0)) 818f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return -1; 81986924b4182537745659f2660244f3402c1e1ca4dJack Carter return getReg(Mips::AFGR64RegClassID, IntVal / 2); 820f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 821f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 822f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 823ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 824ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 82586924b4182537745659f2660244f3402c1e1ca4dJack Carter 826f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() { 827f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 828f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (isMips64() || isFP64()) 829f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_D; 830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else 831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = FP_FORMAT_S; 832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 833f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 834f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("ldxc1", true) 838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("ldc1", true) 839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("sdxc1", true) 840f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case("sdc1", true) 841f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(false); 842f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 843f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return IsDouble; 844f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 84586924b4182537745659f2660244f3402c1e1ca4dJack Carter 846f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) { 847f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 848f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 849f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".s", FP_FORMAT_S) 850f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".d", FP_FORMAT_D) 851f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".l", FP_FORMAT_L) 852f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Case(".w", FP_FORMAT_W) 853f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter .Default(FP_FORMAT_NONE); 854f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 855ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 85630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) { 85730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Reg > 31) 85830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 85930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 86030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter aTReg = Reg; 86130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 86230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 86330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 86499e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::getATReg() { 86599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return Options.getATRegNum(); 86630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 86730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 86886924b4182537745659f2660244f3402c1e1ca4dJack Carterunsigned MipsAsmParser::getReg(int RC, int RegNo) { 869ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); 870ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 871ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 872ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 873ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 874ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNum > 31) 875ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return -1; 876ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 877ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return getReg(RegClass, RegNum); 878ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 879ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 880ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::tryParseRegister(bool is64BitReg) { 881ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const AsmToken &Tok = Parser.getTok(); 882ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNum = -1; 883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 884ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (Tok.is(AsmToken::Identifier)) { 885ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter std::string lowerCase = Tok.getString().lower(); 886ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNum = matchRegisterName(lowerCase, is64BitReg); 887ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } else if (Tok.is(AsmToken::Integer)) 8889d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 88986924b4182537745659f2660244f3402c1e1ca4dJack Carter is64BitReg ? Mips::CPU64RegsRegClassID : Mips::CPURegsRegClassID); 890ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return RegNum; 891ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 892ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 89386924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::tryParseRegisterOperand( 89486924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) { 895ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 896ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 897ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter int RegNo = -1; 898f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 899ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNo = tryParseRegister(is64BitReg); 900ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (RegNo == -1) 901ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 902ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 903ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(MipsOperand::CreateReg(RegNo, S, 90486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc())); 905ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat register token. 906ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 907ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 908ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 909ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 910ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Mnemonic) { 9119d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // Check if the current operand has a custom associated parser, if so, try to 9129d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter // custom parse the operand, or fallback to the general approach. 913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 914ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_Success) 915ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 916ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // If there wasn't a custom match, try the generic matcher below. Otherwise, 917ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // there was a match, but an error occurred, in which case, just return that 918ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // the operand parsing failed. 919ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ResTy == MatchOperand_ParseFail) 920ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 921ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 922ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter switch (getLexer().getKind()) { 923ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter default: 924ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 925ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 926ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Dollar: { 92786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Parse the register. 928ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 929ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); // Eat dollar token. 93086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Parse the register operand. 931ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (!tryParseRegisterOperand(Operands, isMips64())) { 932ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().is(AsmToken::LParen)) { 93386924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check if it is indexed addressing operand. 934ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken("(", S)); 93586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the parenthesis. 936ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::Dollar)) 937ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 938ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 93986924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the dollar 940ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (tryParseRegisterOperand(Operands, isMips64())) 941ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 942ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 943ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (!getLexer().is(AsmToken::RParen)) 944ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 945ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 946ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter S = Parser.getTok().getLoc(); 947ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateToken(")", S)); 948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Parser.Lex(); 949ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 95286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Maybe it is a symbol reference. 953ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StringRef Identifier; 954cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (Parser.parseIdentifier(Identifier)) 955ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 956ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 957ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 958ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 95938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 960ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 96186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Otherwise create a symbol reference. 9626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 963ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter getContext()); 964ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 965ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 966ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 967ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 968ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Identifier: 969c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter // Look for the existing symbol, we should check if 97086924b4182537745659f2660244f3402c1e1ca4dJack Carter // we need to assigne the propper RegisterKind. 97186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (searchSymbolAlias(Operands, MipsOperand::Kind_None)) 97286924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 97386924b4182537745659f2660244f3402c1e1ca4dJack Carter // Else drop to expression parsing. 974ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::LParen: 975ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Minus: 976ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Plus: 977ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::Integer: 978ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter case AsmToken::String: { 97986924b4182537745659f2660244f3402c1e1ca4dJack Carter // Quoted label names. 980ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter const MCExpr *IdVal; 981ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc S = Parser.getTok().getLoc(); 982cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(IdVal)) 983ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return true; 984ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 985ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 986ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 987ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 9886b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Percent: { 98986924b4182537745659f2660244f3402c1e1ca4dJack Carter // It is a symbol reference or constant expression. 9906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 99186924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 992ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (parseRelocOperand(IdVal)) 9936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 9946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 995ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 996ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 9976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 9986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return false; 99930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // case AsmToken::Percent 100030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } // switch(getLexer().getKind()) 1001fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 1002fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1003fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 10048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterconst MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 10058afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter StringRef RelocStr) { 10068afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter const MCExpr *Res; 100786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check the type of the expression. 10088afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 100986924b4182537745659f2660244f3402c1e1ca4dJack Carter // It's a constant, evaluate lo or hi value. 10108afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (RelocStr == "lo") { 10118afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter short Val = MCE->getValue(); 10128afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Res = MCConstantExpr::Create(Val, getContext()); 10138afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } else if (RelocStr == "hi") { 10148afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter int Val = MCE->getValue(); 10158afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter int LoSign = Val & 0x8000; 10168afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Val = (Val & 0xffff0000) >> 16; 10178afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter // Lower part is treated as a signed int, so if it is negative 101886924b4182537745659f2660244f3402c1e1ca4dJack Carter // we must add 1 to the hi part to compensate. 10198afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (LoSign) 10208afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Val++; 10218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Res = MCConstantExpr::Create(Val, getContext()); 1022ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov } else { 1023ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov llvm_unreachable("Invalid RelocStr value"); 10248afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 102586924b4182537745659f2660244f3402c1e1ca4dJack Carter return Res; 10268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 102986924b4182537745659f2660244f3402c1e1ca4dJack Carter // It's a symbol, create a symbolic expression from the symbol. 10308afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter StringRef Symbol = MSRE->getSymbol().getName(); 10318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 103286924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 10338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Res; 10348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10358afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10368afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 103786924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 103886924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 10398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 10408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Res; 10418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10428afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 104486924b4182537745659f2660244f3402c1e1ca4dJack Carter const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 104586924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 104686924b4182537745659f2660244f3402c1e1ca4dJack Carter return Res; 10478afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 104886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Just return the original expression. 10498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Expr; 10508afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter} 10518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10528afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 10538afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 10548afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter switch (Expr->getKind()) { 10558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Constant: 10568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return true; 10578afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::SymbolRef: 10588afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 10598afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Binary: 10608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 10618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (!isEvaluated(BE->getLHS())) 10628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 10638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return isEvaluated(BE->getRHS()); 10648afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10658afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case MCExpr::Unary: 10668afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 10678afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter default: 10688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 10698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 10708afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 10718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter} 10726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 107386924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 107486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the % token. 107586924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 10766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok.isNot(AsmToken::Identifier)) 10776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 10786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 107938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer std::string Str = Tok.getIdentifier().str(); 10806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 108186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the identifier. 108286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Now make an expression from the rest of the operand. 10836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal; 1084ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc EndLoc; 10856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 10866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::LParen) { 10876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter while (1) { 108886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '(' token. 10896b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() == AsmToken::Percent) { 109086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the % token. 10916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const AsmToken &nextTok = Parser.getTok(); 10926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (nextTok.isNot(AsmToken::Identifier)) 10936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 109438539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += "(%"; 109538539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer Str += nextTok.getIdentifier(); 109686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the identifier. 10976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (getLexer().getKind() != AsmToken::LParen) 10986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 10996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 11006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter break; 11016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 110286924b4182537745659f2660244f3402c1e1ca4dJack Carter if (getParser().parseParenExpression(IdVal, EndLoc)) 11036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 11046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1105ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter while (getLexer().getKind() == AsmToken::RParen) 110686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the ')' token. 11076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else 110986924b4182537745659f2660244f3402c1e1ca4dJack Carter return true; // Parenthesis must follow the relocation operand. 11106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 111186924b4182537745659f2660244f3402c1e1ca4dJack Carter Res = evaluateRelocExpr(IdVal, Str); 11128afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return false; 11136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 11146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1115ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1116ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc &EndLoc) { 1117ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter StartLoc = Parser.getTok().getLoc(); 1118ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNo = tryParseRegister(isMips64()); 1119ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter EndLoc = Parser.getTok().getLoc(); 112086924b4182537745659f2660244f3402c1e1ca4dJack Carter return (RegNo == (unsigned) -1); 1121ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1122ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 11238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1124ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 11258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool Result = true; 11268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 11278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter while (getLexer().getKind() == AsmToken::LParen) 11288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 1129ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 113086924b4182537745659f2660244f3402c1e1ca4dJack Carter switch (getLexer().getKind()) { 11316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter default: 11326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return true; 113325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter case AsmToken::Identifier: 11348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter case AsmToken::LParen: 11356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Integer: 11366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Minus: 11376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter case AsmToken::Plus: 11388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (isParenExpr) 113986924b4182537745659f2660244f3402c1e1ca4dJack Carter Result = getParser().parseParenExpression(Res, S); 11408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter else 11418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Result = (getParser().parseExpression(Res)); 114286924b4182537745659f2660244f3402c1e1ca4dJack Carter while (getLexer().getKind() == AsmToken::RParen) 11438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 114486924b4182537745659f2660244f3402c1e1ca4dJack Carter break; 1145ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter case AsmToken::Percent: 11468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Result = parseRelocOperand(Res); 11476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 11488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return Result; 11496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 11506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1151ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 115286924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 11536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter const MCExpr *IdVal = 0; 1155ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S; 11568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter bool isParenExpr = false; 115786924b4182537745659f2660244f3402c1e1ca4dJack Carter // First operand is the offset. 1158ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter S = Parser.getTok().getLoc(); 11596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (getLexer().getKind() == AsmToken::LParen) { 11618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Parser.Lex(); 11628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter isParenExpr = true; 11638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 11646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11658afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (getLexer().getKind() != AsmToken::Dollar) { 116686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (parseMemOffset(IdVal, isParenExpr)) 11678afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_ParseFail; 11688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 116986924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get the next token. 11708afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Tok.isNot(AsmToken::LParen)) { 11718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 11728afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Mnemonic->getToken() == "la") { 11738afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter SMLoc E = SMLoc::getFromPointer( 117486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc().getPointer() - 1); 11758afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 11768afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_Success; 11778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 11788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (Tok.is(AsmToken::EndOfStatement)) { 11798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter SMLoc E = SMLoc::getFromPointer( 118086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc().getPointer() - 1); 11818afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 118286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Zero register assumed, add a memory operand with ZERO as its base. 118386924b4182537745659f2660244f3402c1e1ca4dJack Carter Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64 118486924b4182537745659f2660244f3402c1e1ca4dJack Carter : Mips::ZERO, 118586924b4182537745659f2660244f3402c1e1ca4dJack Carter IdVal, S, E)); 11868afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_Success; 11878afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 11888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Error(Parser.getTok().getLoc(), "'(' expected"); 11898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter return MatchOperand_ParseFail; 11902f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter } 11916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 119286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '(' token. 11938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 11946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 11958afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter const AsmToken &Tok1 = Parser.getTok(); // Get next token 11966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok1.is(AsmToken::Dollar)) { 119786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$' token. 1198ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (tryParseRegisterOperand(Operands, isMips64())) { 11996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 12006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 12016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 12026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 12036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } else { 120430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Error(Parser.getTok().getLoc(), "unexpected token in operand"); 12056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 12066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 12076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 120886924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok2 = Parser.getTok(); // Get next token. 12096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (Tok2.isNot(AsmToken::RParen)) { 12106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Error(Parser.getTok().getLoc(), "')' expected"); 12116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return MatchOperand_ParseFail; 12126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter } 12136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 1214ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1215ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 121686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the ')' token. 12176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 12186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter if (IdVal == 0) 12196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter IdVal = MCConstantExpr::Create(0, getContext()); 12206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 122186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Replace the register operand with the memory operand. 12226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 12236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter int RegNo = op->getReg(); 122486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Remove the register from the operands. 12256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.pop_back(); 122686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add the memory operand. 12278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 12288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter int64_t Imm; 12298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter if (IdVal->EvaluateAsAbsolute(Imm)) 12308afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter IdVal = MCConstantExpr::Create(Imm, getContext()); 12318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 12328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 12338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter getContext()); 12348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter } 12358afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter 12366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 12376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter delete op; 1238ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return MatchOperand_Success; 1239ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter} 1240ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1241ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1242ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1243ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1244ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (!isMips64()) 1245ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1246c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().getKind() == AsmToken::Identifier) { 124786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (searchSymbolAlias(Operands, MipsOperand::Kind_CPU64Regs)) 1248c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_Success; 1249c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_NoMatch; 1250c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 125186924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$', we have an error. 1252ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1253ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1254ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1255ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 125686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (!tryParseRegisterOperand(Operands, true)) { 125786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Set the proper register kind. 1258ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1259ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_CPU64Regs); 1260ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1261ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 1262ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1263ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1264ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 126586924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::searchSymbolAlias( 126686924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegisterKind) { 1267c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1268c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1269c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Sym) { 1270c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter SMLoc S = Parser.getTok().getLoc(); 1271c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCExpr *Expr; 1272c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Sym->isVariable()) 1273c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Expr = Sym->getVariableValue(); 1274c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter else 1275c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1276c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Expr->getKind() == MCExpr::SymbolRef) { 1277c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1278c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const StringRef DefSymbol = Ref->getSymbol().getName(); 1279c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (DefSymbol.startswith("$")) { 128086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Lookup for the register with the corresponding name. 128186924b4182537745659f2660244f3402c1e1ca4dJack Carter int RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); 1282c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (RegNum > -1) { 1283c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.Lex(); 128486924b4182537745659f2660244f3402c1e1ca4dJack Carter MipsOperand *op = MipsOperand::CreateReg(RegNum, S, 128586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 128686924b4182537745659f2660244f3402c1e1ca4dJack Carter op->setRegKind((MipsOperand::RegisterKind) RegisterKind); 1287c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Operands.push_back(op); 1288c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return true; 1289c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1290c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1291c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } else if (Expr->getKind() == MCExpr::Constant) { 1292c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Parser.Lex(); 1293c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 129486924b4182537745659f2660244f3402c1e1ca4dJack Carter MipsOperand *op = MipsOperand::CreateImm(Const, S, 129586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 1296c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Operands.push_back(op); 1297c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return true; 1298c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1299c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 1300c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1301c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter} 130286924b4182537745659f2660244f3402c1e1ca4dJack Carter 1303ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1304ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1305ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1306c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().getKind() == AsmToken::Identifier) { 130786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (searchSymbolAlias(Operands, MipsOperand::Kind_CPURegs)) 1308c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_Success; 1309c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return MatchOperand_NoMatch; 1310c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } 131186924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$' we have an error. 1312ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1313ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1314ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1315ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 131686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (!tryParseRegisterOperand(Operands, false)) { 131786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Set the proper register kind. 1318ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1319ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_CPURegs); 1320ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1321ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } 1322ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1323ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1324ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1325ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1326ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1327ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1328c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter if (isMips64()) 1329c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter return MatchOperand_NoMatch; 1330c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter 133186924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$' we have error. 1332ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1333ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1334ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 133586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$'. 1336ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 133786924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get the next token. 1338ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.isNot(AsmToken::Integer)) 1339ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1340ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1341ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum = Tok.getIntVal(); 134286924b4182537745659f2660244f3402c1e1ca4dJack Carter // At the moment only hwreg29 is supported. 1343ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 29) 1344ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1345ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1346ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 134786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 1348ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_HWRegs); 1349ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1350ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 135186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the register number. 1352ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1353ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1354ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1355ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 135686924b4182537745659f2660244f3402c1e1ca4dJack CarterMipsAsmParser::parseHW64Regs( 135786924b4182537745659f2660244f3402c1e1ca4dJack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1358c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter 1359c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter if (!isMips64()) 1360c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter return MatchOperand_NoMatch; 136186924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$' we have an error. 1362ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1363ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1364ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 1365ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Parser.Lex(); // Eat $ 1366ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 136786924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get the next token. 1368ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.isNot(AsmToken::Integer)) 1369ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1370ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1371ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum = Tok.getIntVal(); 137286924b4182537745659f2660244f3402c1e1ca4dJack Carter // At the moment only hwreg29 is supported. 1373ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 29) 1374ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1375ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1376ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 137786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 1378c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter op->setRegKind(MipsOperand::Kind_HW64Regs); 1379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 138186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the register number. 1382ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1383ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1385ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy 1386ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter unsigned RegNum; 138886924b4182537745659f2660244f3402c1e1ca4dJack Carter // If the first token is not '$' we have an error. 1389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Parser.getTok().isNot(AsmToken::Dollar)) 1390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc S = Parser.getTok().getLoc(); 139286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$' 1393ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 139486924b4182537745659f2660244f3402c1e1ca4dJack Carter const AsmToken &Tok = Parser.getTok(); // Get next token. 1395ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.is(AsmToken::Integer)) { 1396ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter RegNum = Tok.getIntVal(); 139786924b4182537745659f2660244f3402c1e1ca4dJack Carter // At the moment only fcc0 is supported. 1398ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (RegNum != 0) 1399ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1400ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } else if (Tok.is(AsmToken::Identifier)) { 140186924b4182537745659f2660244f3402c1e1ca4dJack Carter // At the moment only fcc0 is supported. 1402ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter if (Tok.getIdentifier() != "fcc0") 1403ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_ParseFail; 1404ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter } else 1405ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_NoMatch; 1406ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 1407ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 140886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc()); 1409ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter op->setRegKind(MipsOperand::Kind_CCRRegs); 1410ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter Operands.push_back(op); 1411ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 141286924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the register number. 1413ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter return MatchOperand_Success; 1414ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter} 1415ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter 14166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 14176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 14186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter MCSymbolRefExpr::VariantKind VK 14196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 14206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 14216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 14226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 14236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 14246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 14256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 14266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 14276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 14286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 14296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 14306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 14316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 14326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 14336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 14346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 14356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 14366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 14376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter .Default(MCSymbolRefExpr::VK_None); 14386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 14396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter return VK; 14406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter} 14416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter 14421ac4587eb32e639576973b793d465c5d9577bef7Benjamin Kramerstatic int ConvertCcString(StringRef CondString) { 1443f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter int CC = StringSwitch<unsigned>(CondString) 144486924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".f", 0) 144586924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".un", 1) 144686924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".eq", 2) 144786924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".ueq", 3) 144886924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".olt", 4) 144986924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".ult", 5) 145086924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".ole", 6) 145186924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".ule", 7) 145286924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".sf", 8) 145386924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".ngle", 9) 145486924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".seq", 10) 145586924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".ngl", 11) 145686924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".lt", 12) 145786924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".nge", 13) 145886924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".le", 14) 145986924b4182537745659f2660244f3402c1e1ca4dJack Carter .Case(".ngt", 15) 146086924b4182537745659f2660244f3402c1e1ca4dJack Carter .Default(-1); 1461f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1462f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return CC; 1463f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 1464f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1465f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser:: 1466f740d6e328bd10904b079e1ce6583f436d6c9817Jack CarterparseMathOperation(StringRef Name, SMLoc NameLoc, 146730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 146886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Split the format. 1469f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Start = Name.find('.'), Next = Name.rfind('.'); 1470f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format1 = Name.slice(Start, Next); 147186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Add the first format to the operands. 1472f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 147386924b4182537745659f2660244f3402c1e1ca4dJack Carter // Now for the second format. 1474f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format2 = Name.slice(Next, StringRef::npos); 1475f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1476f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 147786924b4182537745659f2660244f3402c1e1ca4dJack Carter // Set the format for the first register. 1478f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format1); 1479f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1480f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Read the remaining operands. 1481f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1482f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Read the first operand. 1483f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (ParseOperand(Operands, Name)) { 1484f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1485cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1486f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1487f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1488f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1489f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::Comma)) { 1490f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1491cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1492f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1493f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 149486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the comma. 1495f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 14968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter // Set the format for the first register 1497f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format2); 1498f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1499f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Parse and remember the operand. 1500f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (ParseOperand(Operands, Name)) { 1501f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1502cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1503f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1504f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1505f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1506f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1507f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1508f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter SMLoc Loc = getLexer().getLoc(); 1509cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1510f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(Loc, "unexpected token in argument list"); 1511f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1512f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 151386924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 1514f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return false; 1515f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter} 1516f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1517fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser:: 15186a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1519fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 152099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter StringRef Mnemonic; 152186924b4182537745659f2660244f3402c1e1ca4dJack Carter // Floating point instructions: Should the register be treated as a double? 1522f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (requestsDoubleOperand(Name)) { 1523f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(FP_FORMAT_D); 152486924b4182537745659f2660244f3402c1e1ca4dJack Carter Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 152586924b4182537745659f2660244f3402c1e1ca4dJack Carter Mnemonic = Name; 152686924b4182537745659f2660244f3402c1e1ca4dJack Carter } else { 1527f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setDefaultFpFormat(); 1528f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter // Create the leading tokens for the mnemonic, split by '.' characters. 1529f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter size_t Start = 0, Next = Name.find('.'); 153099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter Mnemonic = Name.slice(Start, Next); 1531f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1532f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1533f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1534f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Next != StringRef::npos) { 153586924b4182537745659f2660244f3402c1e1ca4dJack Carter // There is a format token in mnemonic. 153686924b4182537745659f2660244f3402c1e1ca4dJack Carter size_t Dot = Name.find('.', Next + 1); 1537f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter StringRef Format = Name.slice(Next, Dot); 153886924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Dot == StringRef::npos) // Only one '.' in a string, it's a format. 1539f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1540f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter else { 154186924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Name.startswith("c.")) { 154286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Floating point compare, add '.' and immediate represent for cc. 1543f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1544f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter int Cc = ConvertCcString(Format); 1545f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter if (Cc == -1) { 1546f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return Error(NameLoc, "Invalid conditional code"); 1547f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1548ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter SMLoc E = SMLoc::getFromPointer( 154986924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.getTok().getLoc().getPointer() - 1); 155086924b4182537745659f2660244f3402c1e1ca4dJack Carter Operands.push_back( 155186924b4182537745659f2660244f3402c1e1ca4dJack Carter MipsOperand::CreateImm(MCConstantExpr::Create(Cc, getContext()), 155286924b4182537745659f2660244f3402c1e1ca4dJack Carter NameLoc, E)); 1553f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } else { 155430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // trunc, ceil, floor ... 1555f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter return parseMathOperation(Name, NameLoc, Operands); 1556f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1557f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 155886924b4182537745659f2660244f3402c1e1ca4dJack Carter // The rest is a format. 1559f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Format = Name.slice(Dot, StringRef::npos); 1560f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1561f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1562f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter 1563f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter setFpFormat(Format); 1564f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1565f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter } 1566ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1567ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the remaining operands. 1568ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1569ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Read the first operand. 157099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (ParseOperand(Operands, Mnemonic)) { 1571ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1572cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1573ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1574ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1575ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 157686924b4182537745659f2660244f3402c1e1ca4dJack Carter while (getLexer().is(AsmToken::Comma)) { 157786924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the comma. 1578ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1579ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter // Parse and remember the operand. 1580ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (ParseOperand(Operands, Name)) { 1581ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1582cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1583ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1584ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1585ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1586ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1587ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1588ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1589ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter SMLoc Loc = getLexer().getLoc(); 1590cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1591ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return Error(Loc, "unexpected token in argument list"); 1592ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter } 1593ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 159486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 1595ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter return false; 1596fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1597fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 159830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 159986924b4182537745659f2660244f3402c1e1ca4dJack Carter SMLoc Loc = getLexer().getLoc(); 160086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.eatToEndOfStatement(); 160186924b4182537745659f2660244f3402c1e1ca4dJack Carter return Error(Loc, ErrorMsg); 160230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 160330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 160430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() { 160586924b4182537745659f2660244f3402c1e1ca4dJack Carter // Line should look like: ".set noat". 160686924b4182537745659f2660244f3402c1e1ca4dJack Carter // set at reg to 0. 160710d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(0); 160830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // eat noat 160930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 161086924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 161130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 161230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 161330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 161430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 161586924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 161630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 161730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 161886924b4182537745659f2660244f3402c1e1ca4dJack Carter 161930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() { 162086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Line can be .set at - defaults to $1 162130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter // or .set at=$reg 162299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter int AtRegNo; 162330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter getParser().Lex(); 162430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().is(AsmToken::EndOfStatement)) { 162510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setATReg(1); 162686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 162730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 162830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (getLexer().is(AsmToken::Equal)) { 162986924b4182537745659f2660244f3402c1e1ca4dJack Carter getParser().Lex(); // Eat the '='. 163030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::Dollar)) { 163130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 163230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 163330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 163486924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Eat the '$'. 163599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter const AsmToken &Reg = Parser.getTok(); 163699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (Reg.is(AsmToken::Identifier)) { 163799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 163899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else if (Reg.is(AsmToken::Integer)) { 163999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter AtRegNo = Reg.getIntVal(); 164099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } else { 164130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 164230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 164330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 164499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 164586924b4182537745659f2660244f3402c1e1ca4dJack Carter if (AtRegNo < 1 || AtRegNo > 31) { 164699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter reportParseError("unexpected token in statement"); 164799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter return false; 164899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter } 164999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter 165099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter if (!Options.setATReg(AtRegNo)) { 165130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 165230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 165330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 165486924b4182537745659f2660244f3402c1e1ca4dJack Carter getParser().Lex(); // Eat the register. 165530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 165630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 165730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 165830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 165986924b4182537745659f2660244f3402c1e1ca4dJack Carter } 166086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 166130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 166230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else { 166330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 166430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 166530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 166630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 166730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 166830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() { 166930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 167086924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 167130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 167230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 167330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 167430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 167510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setReorder(); 167686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 167730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 167830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 167930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 168030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() { 168186924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); 168286924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 168386924b4182537745659f2660244f3402c1e1ca4dJack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 168486924b4182537745659f2660244f3402c1e1ca4dJack Carter reportParseError("unexpected token in statement"); 168530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 168686924b4182537745659f2660244f3402c1e1ca4dJack Carter } 168786924b4182537745659f2660244f3402c1e1ca4dJack Carter Options.setNoreorder(); 168886924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 168986924b4182537745659f2660244f3402c1e1ca4dJack Carter return false; 169030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 169130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 169230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() { 169330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 169486924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 169530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 169630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("unexpected token in statement"); 169730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 169830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 169910d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setMacro(); 170086924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 170130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 170230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 170330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 170430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() { 170530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter Parser.Lex(); 170686924b4182537745659f2660244f3402c1e1ca4dJack Carter // If this is not the end of the statement, report an error. 170730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 170830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 170930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 171030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 171110d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter if (Options.isReorder()) { 171230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter reportParseError("`noreorder' must be set before `nomacro'"); 171330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 171430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 171510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter Options.setNomacro(); 171686924b4182537745659f2660244f3402c1e1ca4dJack Carter Parser.Lex(); // Consume the EndOfStatement. 171730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 171830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 1719c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1720c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() { 1721c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter StringRef Name; 1722c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter const MCExpr *Value; 1723c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1724c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Parser.parseIdentifier(Name)) 1725c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter reportParseError("expected identifier after .set"); 1726c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1727c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (getLexer().isNot(AsmToken::Comma)) 1728c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("unexpected token in .set directive"); 17298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter Lex(); // Eat comma 1730c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1731c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter if (Parser.parseExpression(Value)) 1732c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter reportParseError("expected valid expression after comma"); 1733c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 173486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Check if the Name already exists as a symbol. 1735c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter MCSymbol *Sym = getContext().LookupSymbol(Name); 173686924b4182537745659f2660244f3402c1e1ca4dJack Carter if (Sym) 1737c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return reportParseError("symbol already defined"); 1738c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym = getContext().GetOrCreateSymbol(Name); 1739c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter Sym->setVariableValue(Value); 1740c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter 1741c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 1742c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter} 174386924b4182537745659f2660244f3402c1e1ca4dJack Carter 174430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() { 174530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 174686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Get the next token. 174730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter const AsmToken &Tok = Parser.getTok(); 174830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 174930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter if (Tok.getString() == "noat") { 175030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoAtDirective(); 175130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "at") { 175230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetAtDirective(); 175330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "reorder") { 175430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetReorderDirective(); 175530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "noreorder") { 175630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoReorderDirective(); 175730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "macro") { 175830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetMacroDirective(); 175930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomacro") { 176030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseSetNoMacroDirective(); 176130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomips16") { 176286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1763cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 176430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 176530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } else if (Tok.getString() == "nomicromips") { 176686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1767cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 176830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return false; 1769c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter } else { 177086924b4182537745659f2660244f3402c1e1ca4dJack Carter // It is just an identifier, look for an assignment. 1771c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter parseSetAssignment(); 1772c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter return false; 177330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter } 1774801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 177530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return true; 177630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter} 177730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter 1778801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// parseDirectiveWord 1779801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// ::= .word [ expression (, expression)* ] 1780801c5838830d190a6b0d8e462bd43805f66ba50fJack Carterbool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1781801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::EndOfStatement)) { 1782801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter for (;;) { 1783801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter const MCExpr *Value; 1784cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Value)) 1785801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return true; 1786801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1787801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter getParser().getStreamer().EmitValue(Value, Size); 1788801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1789801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().is(AsmToken::EndOfStatement)) 1790801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter break; 1791801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1792801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter // FIXME: Improve diagnostic. 1793801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (getLexer().isNot(AsmToken::Comma)) 1794801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return Error(L, "unexpected token in directive"); 1795801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 1796801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1797801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1798801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1799801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter Parser.Lex(); 1800801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 1801801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter} 1802801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 180330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1804acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1805801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter StringRef IDVal = DirectiveID.getString(); 1806801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 180786924b4182537745659f2660244f3402c1e1ca4dJack Carter if (IDVal == ".ent") { 180886924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1809acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 1810acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1811acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1812acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1813801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".end") { 181486924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1815acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter Parser.Lex(); 1816acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1817acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1818acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1819801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".frame") { 182086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1821cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1822acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1823acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1824acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1825801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".set") { 182630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter return parseDirectiveSet(); 1827acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1828acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1829801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".fmask") { 183086924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1831cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1832acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1833acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1834acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1835801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".mask") { 183686924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1837cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1838acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1839acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1840acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1841801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".gpword") { 184286924b4182537745659f2660244f3402c1e1ca4dJack Carter // Ignore this directive for now. 1843cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach Parser.eatToEndOfStatement(); 1844acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter return false; 1845acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter } 1846acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter 1847801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter if (IDVal == ".word") { 1848801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter parseDirectiveWord(4, DirectiveID.getLoc()); 1849801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter return false; 1850801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter } 1851801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter 1852fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola return true; 1853fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1854fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola 1855fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() { 1856fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1857fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1858fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1859fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1860fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola} 1861ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter 1862ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER 1863ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION 1864ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc" 1865