blob: 8c0c181feca692646aeed23b839584aa075497e0 [file] [log] [blame]
Jia Liu9f610112012-02-17 08:55:11 +00001//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
Rafael Espindola870c4e92012-01-11 03:56:41 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Petar Jovanovica5da5882014-02-04 18:41:57 +000010#include "MCTargetDesc/MipsMCExpr.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000011#include "MCTargetDesc/MipsMCTargetDesc.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000012#include "MipsRegisterInfo.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000013#include "MipsTargetStreamer.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000014#include "llvm/ADT/APInt.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000015#include "llvm/ADT/StringSwitch.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
Daniel Sandersa771fef2014-03-24 14:05:39 +000019#include "llvm/MC/MCInstBuilder.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000022#include "llvm/MC/MCStreamer.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000025#include "llvm/MC/MCTargetAsmParser.h"
Matheus Almeidae0d75aa2013-12-13 11:11:02 +000026#include "llvm/Support/MathExtras.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000027#include "llvm/Support/TargetRegistry.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000028
29using namespace llvm;
30
Joey Gouly0e76fa72013-09-12 10:28:05 +000031namespace llvm {
32class MCInstrInfo;
33}
34
Rafael Espindola870c4e92012-01-11 03:56:41 +000035namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000036class MipsAssemblerOptions {
37public:
Vladimir Medic4c299852013-11-06 11:27:05 +000038 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
Jack Carterb4dbc172012-09-05 23:34:03 +000039
Vladimir Medic4c299852013-11-06 11:27:05 +000040 unsigned getATRegNum() { return aTReg; }
Jack Carter0b744b32012-10-04 02:29:46 +000041 bool setATReg(unsigned Reg);
42
Vladimir Medic4c299852013-11-06 11:27:05 +000043 bool isReorder() { return reorder; }
44 void setReorder() { reorder = true; }
45 void setNoreorder() { reorder = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000046
Vladimir Medic4c299852013-11-06 11:27:05 +000047 bool isMacro() { return macro; }
48 void setMacro() { macro = true; }
49 void setNomacro() { macro = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000050
51private:
52 unsigned aTReg;
53 bool reorder;
54 bool macro;
55};
56}
57
58namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000059class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000060
Rafael Espindolaa17151a2013-10-08 13:08:17 +000061 MipsTargetStreamer &getTargetStreamer() {
Rafael Espindola4a1a3602014-01-14 01:21:46 +000062 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
Rafael Espindolaa17151a2013-10-08 13:08:17 +000063 return static_cast<MipsTargetStreamer &>(TS);
64 }
65
Jack Carterb4dbc172012-09-05 23:34:03 +000066 MCSubtargetInfo &STI;
67 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000068 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000069 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000070
Akira Hatanaka7605630c2012-08-17 20:16:42 +000071#define GET_ASSEMBLER_HEADER
72#include "MipsGenAsmMatcher.inc"
73
Chad Rosier49963552012-10-13 00:26:04 +000074 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Vladimir Medic4c299852013-11-06 11:27:05 +000075 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000076 MCStreamer &Out, unsigned &ErrorInfo,
77 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000078
79 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
80
Chad Rosierf0e87202012-10-25 20:41:34 +000081 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
82 SMLoc NameLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +000083 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000084
85 bool ParseDirective(AsmToken DirectiveID);
86
Jack Carterb4dbc172012-09-05 23:34:03 +000087 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000088 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000089
90 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000091 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Jack Carter5dc8ac92013-09-25 23:50:44 +000092
93 MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +000094 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
95 int RegKind);
96
97 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000098 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000099
Vladimir Medic4c299852013-11-06 11:27:05 +0000100 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
101 int RegKind);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000102
103 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000104 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000105
Jack Carter873c7242013-01-12 01:03:14 +0000106 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000107 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000108
109 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000110 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000111
112 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000113 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000114
115 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000116 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000117
Vladimir Medic233dd512013-06-24 10:05:34 +0000118 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000119 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000120
121 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000122 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000123
124 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000125 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000126
Vladimir Medic643b3982013-07-30 10:12:14 +0000127 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000128 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000129
130 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000131 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic643b3982013-07-30 10:12:14 +0000132
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000133 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000134 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000135
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000136 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000137 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000138
139 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000140 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000141
Vladimir Medic05bcde62013-09-16 10:29:42 +0000142 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000143 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic05bcde62013-09-16 10:29:42 +0000144
Jack Carter5dc8ac92013-09-25 23:50:44 +0000145 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000146 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000147
148 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000149 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000150
151 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000152 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000153
154 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000155 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000156
Vladimir Medic2b953d02013-10-01 09:48:56 +0000157 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000158 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000159
160 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000161 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic2b953d02013-10-01 09:48:56 +0000162
Matheus Almeida779c5932013-11-18 12:32:49 +0000163 MipsAsmParser::OperandMatchResultTy
164 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
165
Jack Carter3b2c96e2014-01-22 23:31:38 +0000166 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000167 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000168
Vladimir Medic4c299852013-11-06 11:27:05 +0000169 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
Jack Carterb4dbc172012-09-05 23:34:03 +0000170 StringRef Mnemonic);
171
Jack Carter873c7242013-01-12 01:03:14 +0000172 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000173
Vladimir Medic4c299852013-11-06 11:27:05 +0000174 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000175 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000176
Jack Carter30a59822012-10-04 04:03:53 +0000177 bool needsExpansion(MCInst &Inst);
178
179 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000180 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000181 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000182 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000183 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
185 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000187 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000188 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
189 bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000190 bool reportParseError(StringRef ErrorMsg);
191
Jack Carterb5cf5902013-04-17 00:18:04 +0000192 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000193 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000194
Vladimir Medic4c299852013-11-06 11:27:05 +0000195 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000196
197 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000198 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000199 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000200
201 bool parseSetAtDirective();
202 bool parseSetNoAtDirective();
203 bool parseSetMacroDirective();
204 bool parseSetNoMacroDirective();
205 bool parseSetReorderDirective();
206 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000207 bool parseSetMips16Directive();
208 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000209
Jack Carterd76b2372013-03-21 21:44:16 +0000210 bool parseSetAssignment();
211
Jack Carter07c818d2013-01-25 01:31:34 +0000212 bool parseDirectiveWord(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000213 bool parseDirectiveGpWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000214
Jack Carterdc1e35d2012-09-06 20:00:02 +0000215 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000216
Jack Carterb4dbc172012-09-05 23:34:03 +0000217 bool isMips64() const {
218 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
219 }
220
Jack Cartera63b16a2012-09-07 00:23:42 +0000221 bool isFP64() const {
222 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
223 }
224
Vladimir Medic4c299852013-11-06 11:27:05 +0000225 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000226
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000227 bool isMicroMips() const {
228 return STI.getFeatureBits() & Mips::FeatureMicroMips;
229 }
230
Jack Carter873c7242013-01-12 01:03:14 +0000231 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000232
Jack Carter1ac53222013-02-20 23:11:17 +0000233 int matchCPURegisterName(StringRef Symbol);
234
Jack Carter873c7242013-01-12 01:03:14 +0000235 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000236
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000237 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000238
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000239 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000240
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000241 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000242
Jack Carter5dc8ac92013-09-25 23:50:44 +0000243 int matchMSA128RegisterName(StringRef Name);
244
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000245 int matchMSA128CtrlRegisterName(StringRef Name);
246
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000247 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000248
Jack Carterd0bd6422013-04-18 00:41:53 +0000249 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000250
Jack Carter1ac53222013-02-20 23:11:17 +0000251 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000252
253 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000254 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000255
256 // Helper function that checks if the value of a vector index is within the
257 // boundaries of accepted values for each RegisterKind
258 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
259 bool validateMSAIndex(int Val, int RegKind);
260
Vladimir Medic615b26e2014-03-04 09:54:09 +0000261 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
262 if (!(STI.getFeatureBits() & Feature)) {
263 setAvailableFeatures(ComputeAvailableFeatures(
264 STI.ToggleFeature(FeatureString)));
265 }
266 }
267
268 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
269 if (STI.getFeatureBits() & Feature) {
270 setAvailableFeatures(ComputeAvailableFeatures(
271 STI.ToggleFeature(FeatureString)));
272 }
273 }
274
Rafael Espindola870c4e92012-01-11 03:56:41 +0000275public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000276 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
277 const MCInstrInfo &MII)
278 : MCTargetAsmParser(), STI(sti), Parser(parser),
279 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000280 // Initialize the set of available features.
281 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000282
283 // Assert exactly one ABI was chosen.
284 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
285 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
286 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
287 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000288 }
289
Jack Carterb4dbc172012-09-05 23:34:03 +0000290 MCAsmParser &getParser() const { return Parser; }
291 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000292};
293}
294
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000295namespace {
296
297/// MipsOperand - Instances of this class represent a parsed Mips machine
298/// instruction.
299class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000300
Jack Carter873c7242013-01-12 01:03:14 +0000301public:
302 enum RegisterKind {
303 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000304 Kind_GPR32,
305 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000306 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000307 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000308 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000309 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000310 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000311 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000312 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000313 Kind_ACC64DSP,
314 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000315 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000316 Kind_COP2,
317 Kind_MSA128BRegs,
318 Kind_MSA128HRegs,
319 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000320 Kind_MSA128DRegs,
321 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000322 };
323
324private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000325 enum KindTy {
326 k_CondCode,
327 k_CoprocNum,
328 k_Immediate,
329 k_Memory,
330 k_PostIndexRegister,
331 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000332 k_PtrReg,
Matheus Almeida779c5932013-11-18 12:32:49 +0000333 k_Token,
334 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000335 } Kind;
336
337 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000338
Eric Christopher8996c5d2013-03-15 00:42:55 +0000339 struct Token {
340 const char *Data;
341 unsigned Length;
342 };
343
344 struct RegOp {
345 unsigned RegNum;
346 RegisterKind Kind;
347 };
348
349 struct ImmOp {
350 const MCExpr *Val;
351 };
352
353 struct MemOp {
354 unsigned Base;
355 const MCExpr *Off;
356 };
357
Jack Carterb4dbc172012-09-05 23:34:03 +0000358 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000359 struct Token Tok;
360 struct RegOp Reg;
361 struct ImmOp Imm;
362 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000363 };
364
365 SMLoc StartLoc, EndLoc;
366
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000367public:
368 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000369 assert(N == 1 && "Invalid number of operands!");
370 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000371 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000372
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000373 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
374 assert(N == 1 && "Invalid number of operands!");
375 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
376 }
377
Vladimir Medic4c299852013-11-06 11:27:05 +0000378 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000379 // Add as immediate when possible. Null MCExpr = 0.
380 if (Expr == 0)
381 Inst.addOperand(MCOperand::CreateImm(0));
382 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
383 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
384 else
385 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000386 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000387
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000388 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000389 assert(N == 1 && "Invalid number of operands!");
390 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000391 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000392 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000393
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000394 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000395 assert(N == 2 && "Invalid number of operands!");
396
397 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
398
399 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000400 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000401 }
402
403 bool isReg() const { return Kind == k_Register; }
404 bool isImm() const { return Kind == k_Immediate; }
405 bool isToken() const { return Kind == k_Token; }
406 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000407 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000408 bool isInvNum() const { return Kind == k_Immediate; }
Matheus Almeida779c5932013-11-18 12:32:49 +0000409 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000410
411 StringRef getToken() const {
412 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000413 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000414 }
415
416 unsigned getReg() const {
417 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000418 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000419 }
420
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000421 unsigned getPtrReg() const {
422 assert((Kind == k_PtrReg) && "Invalid access!");
423 return Reg.RegNum;
424 }
425
Jack Carter873c7242013-01-12 01:03:14 +0000426 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000427 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000428 Reg.Kind = RegKind;
429 }
430
Jack Carterb4dbc172012-09-05 23:34:03 +0000431 const MCExpr *getImm() const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000432 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000433 return Imm.Val;
434 }
435
Jack Carterdc1e35d2012-09-06 20:00:02 +0000436 unsigned getMemBase() const {
437 assert((Kind == k_Memory) && "Invalid access!");
438 return Mem.Base;
439 }
440
441 const MCExpr *getMemOff() const {
442 assert((Kind == k_Memory) && "Invalid access!");
443 return Mem.Off;
444 }
445
Jack Carterb4dbc172012-09-05 23:34:03 +0000446 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
447 MipsOperand *Op = new MipsOperand(k_Token);
448 Op->Tok.Data = Str.data();
449 Op->Tok.Length = Str.size();
450 Op->StartLoc = S;
451 Op->EndLoc = S;
452 return Op;
453 }
454
455 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
456 MipsOperand *Op = new MipsOperand(k_Register);
457 Op->Reg.RegNum = RegNum;
458 Op->StartLoc = S;
459 Op->EndLoc = E;
460 return Op;
461 }
462
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000463 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
464 MipsOperand *Op = new MipsOperand(k_PtrReg);
465 Op->Reg.RegNum = RegNum;
466 Op->StartLoc = S;
467 Op->EndLoc = E;
468 return Op;
469 }
470
Jack Carterb4dbc172012-09-05 23:34:03 +0000471 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
472 MipsOperand *Op = new MipsOperand(k_Immediate);
473 Op->Imm.Val = Val;
474 Op->StartLoc = S;
475 Op->EndLoc = E;
476 return Op;
477 }
478
Matheus Almeida779c5932013-11-18 12:32:49 +0000479 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
480 MipsOperand *Op = new MipsOperand(k_LSAImm);
481 Op->Imm.Val = Val;
482 Op->StartLoc = S;
483 Op->EndLoc = E;
484 return Op;
485 }
486
Jack Carter3b2c96e2014-01-22 23:31:38 +0000487 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
488 SMLoc E) {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000489 MipsOperand *Op = new MipsOperand(k_Memory);
490 Op->Mem.Base = Base;
491 Op->Mem.Off = Off;
492 Op->StartLoc = S;
493 Op->EndLoc = E;
494 return Op;
495 }
496
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000497 bool isGPR32Asm() const {
498 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000499 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000500 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000501 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
502 }
503
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000504 bool isGPR64Asm() const {
505 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000506 }
Jack Carter873c7242013-01-12 01:03:14 +0000507
508 bool isHWRegsAsm() const {
509 assert((Kind == k_Register) && "Invalid access!");
510 return Reg.Kind == Kind_HWRegs;
511 }
Jack Carter873c7242013-01-12 01:03:14 +0000512
Jack Carter873c7242013-01-12 01:03:14 +0000513 bool isCCRAsm() const {
514 assert((Kind == k_Register) && "Invalid access!");
515 return Reg.Kind == Kind_CCRRegs;
516 }
517
Vladimir Medic4c299852013-11-06 11:27:05 +0000518 bool isAFGR64Asm() const {
Vladimir Medic233dd512013-06-24 10:05:34 +0000519 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
520 }
521
522 bool isFGR64Asm() const {
523 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
524 }
525
526 bool isFGR32Asm() const {
527 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
528 }
529
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000530 bool isFGRH32Asm() const {
531 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
532 }
533
Vladimir Medic643b3982013-07-30 10:12:14 +0000534 bool isFCCRegsAsm() const {
535 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
536 }
537
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000538 bool isACC64DSPAsm() const {
539 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000540 }
541
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000542 bool isLO32DSPAsm() const {
543 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
544 }
545
546 bool isHI32DSPAsm() const {
547 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
548 }
549
Vladimir Medic4c299852013-11-06 11:27:05 +0000550 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
Vladimir Medic05bcde62013-09-16 10:29:42 +0000551
Jack Carter5dc8ac92013-09-25 23:50:44 +0000552 bool isMSA128BAsm() const {
553 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
554 }
555
556 bool isMSA128HAsm() const {
557 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
558 }
559
560 bool isMSA128WAsm() const {
561 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
562 }
563
564 bool isMSA128DAsm() const {
565 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
566 }
567
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000568 bool isMSA128CRAsm() const {
569 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
570 }
571
Jack Carterb4dbc172012-09-05 23:34:03 +0000572 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000573 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000574 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000575 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000576
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000577 virtual void print(raw_ostream &OS) const {
578 llvm_unreachable("unimplemented!");
579 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000580}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000581} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000582
Jack Carter9e65aa32013-03-22 00:05:30 +0000583namespace llvm {
584extern const MCInstrDesc MipsInsts[];
585}
586static const MCInstrDesc &getInstDesc(unsigned Opcode) {
587 return MipsInsts[Opcode];
588}
589
590bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000591 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000592 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000593
Jack Carter9e65aa32013-03-22 00:05:30 +0000594 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000595
596 if (MCID.isBranch() || MCID.isCall()) {
597 const unsigned Opcode = Inst.getOpcode();
598 MCOperand Offset;
599
600 switch (Opcode) {
601 default:
602 break;
603 case Mips::BEQ:
604 case Mips::BNE:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000605 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000606 Offset = Inst.getOperand(2);
607 if (!Offset.isImm())
608 break; // We'll deal with this situation later on when applying fixups.
609 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
610 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000611 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000612 return Error(IDLoc, "branch to misaligned address");
613 break;
614 case Mips::BGEZ:
615 case Mips::BGTZ:
616 case Mips::BLEZ:
617 case Mips::BLTZ:
618 case Mips::BGEZAL:
619 case Mips::BLTZAL:
620 case Mips::BC1F:
621 case Mips::BC1T:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000622 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000623 Offset = Inst.getOperand(1);
624 if (!Offset.isImm())
625 break; // We'll deal with this situation later on when applying fixups.
626 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
627 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000628 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000629 return Error(IDLoc, "branch to misaligned address");
630 break;
631 }
632 }
633
Jack Carterc15c1d22013-04-25 23:31:35 +0000634 if (MCID.hasDelaySlot() && Options.isReorder()) {
635 // If this instruction has a delay slot and .set reorder is active,
636 // emit a NOP after it.
637 Instructions.push_back(Inst);
638 MCInst NopInst;
639 NopInst.setOpcode(Mips::SLL);
640 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
641 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
642 NopInst.addOperand(MCOperand::CreateImm(0));
643 Instructions.push_back(NopInst);
644 return false;
645 }
646
Jack Carter9e65aa32013-03-22 00:05:30 +0000647 if (MCID.mayLoad() || MCID.mayStore()) {
648 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000649 // reference or immediate we may have to expand instructions.
650 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000651 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000652 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
653 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000654 MCOperand &Op = Inst.getOperand(i);
655 if (Op.isImm()) {
656 int MemOffset = Op.getImm();
657 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000658 // Offset can't exceed 16bit value.
659 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000660 return false;
661 }
662 } else if (Op.isExpr()) {
663 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000664 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000665 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000666 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000667 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000668 // Expand symbol.
669 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000670 return false;
671 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000672 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000673 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000674 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000675 }
676 }
677 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000678 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000679 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000680
681 if (needsExpansion(Inst))
682 expandInstruction(Inst, IDLoc, Instructions);
683 else
684 Instructions.push_back(Inst);
685
686 return false;
687}
688
Jack Carter30a59822012-10-04 04:03:53 +0000689bool MipsAsmParser::needsExpansion(MCInst &Inst) {
690
Jack Carterd0bd6422013-04-18 00:41:53 +0000691 switch (Inst.getOpcode()) {
692 case Mips::LoadImm32Reg:
693 case Mips::LoadAddr32Imm:
694 case Mips::LoadAddr32Reg:
Daniel Sandersa771fef2014-03-24 14:05:39 +0000695 case Mips::SUBi:
696 case Mips::SUBiu:
697 case Mips::DSUBi:
698 case Mips::DSUBiu:
Jack Carterd0bd6422013-04-18 00:41:53 +0000699 return true;
700 default:
701 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000702 }
703}
Jack Carter92995f12012-10-06 00:53:28 +0000704
Jack Carter30a59822012-10-04 04:03:53 +0000705void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000706 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000707 switch (Inst.getOpcode()) {
708 case Mips::LoadImm32Reg:
709 return expandLoadImm(Inst, IDLoc, Instructions);
710 case Mips::LoadAddr32Imm:
711 return expandLoadAddressImm(Inst, IDLoc, Instructions);
712 case Mips::LoadAddr32Reg:
713 return expandLoadAddressReg(Inst, IDLoc, Instructions);
Daniel Sandersa771fef2014-03-24 14:05:39 +0000714 case Mips::SUBi:
715 Instructions.push_back(MCInstBuilder(Mips::ADDi)
716 .addReg(Inst.getOperand(0).getReg())
717 .addReg(Inst.getOperand(1).getReg())
718 .addImm(-Inst.getOperand(2).getImm()));
719 return;
720 case Mips::SUBiu:
721 Instructions.push_back(MCInstBuilder(Mips::ADDiu)
722 .addReg(Inst.getOperand(0).getReg())
723 .addReg(Inst.getOperand(1).getReg())
724 .addImm(-Inst.getOperand(2).getImm()));
725 return;
726 case Mips::DSUBi:
727 Instructions.push_back(MCInstBuilder(Mips::DADDi)
728 .addReg(Inst.getOperand(0).getReg())
729 .addReg(Inst.getOperand(1).getReg())
730 .addImm(-Inst.getOperand(2).getImm()));
731 return;
732 case Mips::DSUBiu:
733 Instructions.push_back(MCInstBuilder(Mips::DADDiu)
734 .addReg(Inst.getOperand(0).getReg())
735 .addReg(Inst.getOperand(1).getReg())
736 .addImm(-Inst.getOperand(2).getImm()));
737 return;
Jack Carterd0bd6422013-04-18 00:41:53 +0000738 }
Jack Carter30a59822012-10-04 04:03:53 +0000739}
Jack Carter92995f12012-10-06 00:53:28 +0000740
Jack Carter30a59822012-10-04 04:03:53 +0000741void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000742 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000743 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000744 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000745 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000746 const MCOperand &RegOp = Inst.getOperand(0);
747 assert(RegOp.isReg() && "expected register operand kind");
748
749 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000750 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000751 if (0 <= ImmValue && ImmValue <= 65535) {
752 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000753 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000754 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000755 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000756 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000757 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000758 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000759 } else if (ImmValue < 0 && ImmValue >= -32768) {
760 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000761 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000762 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000763 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000764 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000765 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000766 Instructions.push_back(tmpInst);
767 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000768 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000769 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000770 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000771 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000772 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
773 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000774 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000775 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000776 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000777 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
778 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
779 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
780 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000781 Instructions.push_back(tmpInst);
782 }
783}
Jack Carter92995f12012-10-06 00:53:28 +0000784
Vladimir Medic4c299852013-11-06 11:27:05 +0000785void
786MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
787 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000788 MCInst tmpInst;
789 const MCOperand &ImmOp = Inst.getOperand(2);
790 assert(ImmOp.isImm() && "expected immediate operand kind");
791 const MCOperand &SrcRegOp = Inst.getOperand(1);
792 assert(SrcRegOp.isReg() && "expected register operand kind");
793 const MCOperand &DstRegOp = Inst.getOperand(0);
794 assert(DstRegOp.isReg() && "expected register operand kind");
795 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000796 if (-32768 <= ImmValue && ImmValue <= 65535) {
797 // For -32768 <= j <= 65535.
798 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000799 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000800 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
801 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
802 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
803 Instructions.push_back(tmpInst);
804 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000805 // For any other value of j that is representable as a 32-bit integer.
806 // la d,j(s) => lui d,hi16(j)
807 // ori d,d,lo16(j)
808 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000809 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000810 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
811 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
812 Instructions.push_back(tmpInst);
813 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000814 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000815 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
816 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
817 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
818 Instructions.push_back(tmpInst);
819 tmpInst.clear();
820 tmpInst.setOpcode(Mips::ADDu);
821 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
822 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
823 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
824 Instructions.push_back(tmpInst);
825 }
826}
827
Vladimir Medic4c299852013-11-06 11:27:05 +0000828void
829MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
830 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000831 MCInst tmpInst;
832 const MCOperand &ImmOp = Inst.getOperand(1);
833 assert(ImmOp.isImm() && "expected immediate operand kind");
834 const MCOperand &RegOp = Inst.getOperand(0);
835 assert(RegOp.isReg() && "expected register operand kind");
836 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000837 if (-32768 <= ImmValue && ImmValue <= 65535) {
838 // For -32768 <= j <= 65535.
839 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000840 tmpInst.setOpcode(Mips::ADDiu);
841 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000842 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000843 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
844 Instructions.push_back(tmpInst);
845 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000846 // For any other value of j that is representable as a 32-bit integer.
847 // la d,j => lui d,hi16(j)
848 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000849 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000850 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
851 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
852 Instructions.push_back(tmpInst);
853 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000854 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000855 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
856 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
857 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
858 Instructions.push_back(tmpInst);
859 }
860}
861
Jack Carter9e65aa32013-03-22 00:05:30 +0000862void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000863 SmallVectorImpl<MCInst> &Instructions,
864 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000865 const MCSymbolRefExpr *SR;
866 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000867 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000868 const MCExpr *ExprOffset;
869 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000870 unsigned AtRegNum = getReg(
871 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000872 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000873 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
874 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000875 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000876 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
877 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000878 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000879 if (isImmOpnd) {
880 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
881 ImmOffset = Inst.getOperand(2).getImm();
882 LoOffset = ImmOffset & 0x0000ffff;
883 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000884 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000885 if (LoOffset & 0x8000)
886 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000887 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000888 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000889 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000890 TempInst.setLoc(IDLoc);
891 // 1st instruction in expansion is LUi. For load instruction we can use
892 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000893 // but for stores we must use $at.
894 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000895 TempInst.setOpcode(Mips::LUi);
896 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
897 if (isImmOpnd)
898 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
899 else {
900 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000901 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000902 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
903 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
904 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000905 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000906 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000908 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000909 }
910 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000911 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000912 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000913 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000914 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000915 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000916 TempInst.setOpcode(Mips::ADDu);
917 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
918 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
919 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
920 Instructions.push_back(TempInst);
921 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +0000922 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000923 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000924 TempInst.setOpcode(Inst.getOpcode());
925 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
926 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
927 if (isImmOpnd)
928 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
929 else {
930 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000931 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
932 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
933 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000934 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000935 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000936 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000937 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000938 }
939 }
940 Instructions.push_back(TempInst);
941 TempInst.clear();
942}
943
Vladimir Medic4c299852013-11-06 11:27:05 +0000944bool MipsAsmParser::MatchAndEmitInstruction(
945 SMLoc IDLoc, unsigned &Opcode,
946 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
947 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000948 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000949 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000950 unsigned MatchResult =
951 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000952
953 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000954 default:
955 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000956 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000957 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000958 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000959 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +0000960 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +0000961 return false;
962 }
963 case Match_MissingFeature:
964 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
965 return true;
966 case Match_InvalidOperand: {
967 SMLoc ErrorLoc = IDLoc;
968 if (ErrorInfo != ~0U) {
969 if (ErrorInfo >= Operands.size())
970 return Error(IDLoc, "too few operands for instruction");
971
Vladimir Medic4c299852013-11-06 11:27:05 +0000972 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000973 if (ErrorLoc == SMLoc())
974 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000975 }
976
977 return Error(ErrorLoc, "invalid operand for instruction");
978 }
979 case Match_MnemonicFail:
980 return Error(IDLoc, "invalid instruction");
981 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000982 return true;
983}
984
Jack Carter1ac53222013-02-20 23:11:17 +0000985int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000986 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +0000987
988 if (Name == "at")
989 return getATReg();
990
Vladimir Medic4c299852013-11-06 11:27:05 +0000991 CC = StringSwitch<unsigned>(Name)
992 .Case("zero", 0)
993 .Case("a0", 4)
994 .Case("a1", 5)
995 .Case("a2", 6)
996 .Case("a3", 7)
997 .Case("v0", 2)
998 .Case("v1", 3)
999 .Case("s0", 16)
1000 .Case("s1", 17)
1001 .Case("s2", 18)
1002 .Case("s3", 19)
1003 .Case("s4", 20)
1004 .Case("s5", 21)
1005 .Case("s6", 22)
1006 .Case("s7", 23)
1007 .Case("k0", 26)
1008 .Case("k1", 27)
1009 .Case("sp", 29)
1010 .Case("fp", 30)
1011 .Case("gp", 28)
1012 .Case("ra", 31)
1013 .Case("t0", 8)
1014 .Case("t1", 9)
1015 .Case("t2", 10)
1016 .Case("t3", 11)
1017 .Case("t4", 12)
1018 .Case("t5", 13)
1019 .Case("t6", 14)
1020 .Case("t7", 15)
1021 .Case("t8", 24)
1022 .Case("t9", 25)
1023 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001024
Jack Carterd0bd6422013-04-18 00:41:53 +00001025 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +00001026 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1027 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +00001028 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +00001029 CC += 4;
1030
1031 if (CC == -1 && isMips64())
1032 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001033 .Case("a4", 8)
1034 .Case("a5", 9)
1035 .Case("a6", 10)
1036 .Case("a7", 11)
1037 .Case("kt0", 26)
1038 .Case("kt1", 27)
1039 .Case("s8", 30)
1040 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001041
1042 return CC;
1043}
Jack Carterd0bd6422013-04-18 00:41:53 +00001044
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001045int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001046
Jack Cartera63b16a2012-09-07 00:23:42 +00001047 if (Name[0] == 'f') {
1048 StringRef NumString = Name.substr(1);
1049 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001050 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001051 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001052 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001053 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001054 return IntVal;
1055 }
1056 return -1;
1057}
Jack Cartera63b16a2012-09-07 00:23:42 +00001058
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001059int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1060
1061 if (Name.startswith("fcc")) {
1062 StringRef NumString = Name.substr(3);
1063 unsigned IntVal;
1064 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001065 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001066 if (IntVal > 7) // There are only 8 fcc registers.
1067 return -1;
1068 return IntVal;
1069 }
1070 return -1;
1071}
1072
1073int MipsAsmParser::matchACRegisterName(StringRef Name) {
1074
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001075 if (Name.startswith("ac")) {
1076 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001077 unsigned IntVal;
1078 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001079 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001080 if (IntVal > 3) // There are only 3 acc registers.
1081 return -1;
1082 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001083 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001084 return -1;
1085}
Jack Carterd0bd6422013-04-18 00:41:53 +00001086
Jack Carter5dc8ac92013-09-25 23:50:44 +00001087int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1088 unsigned IntVal;
1089
1090 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1091 return -1;
1092
1093 if (IntVal > 31)
1094 return -1;
1095
1096 return IntVal;
1097}
1098
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001099int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1100 int CC;
1101
1102 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001103 .Case("msair", 0)
1104 .Case("msacsr", 1)
1105 .Case("msaaccess", 2)
1106 .Case("msasave", 3)
1107 .Case("msamodify", 4)
1108 .Case("msarequest", 5)
1109 .Case("msamap", 6)
1110 .Case("msaunmap", 7)
1111 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001112
1113 return CC;
1114}
1115
Vladimir Medic8cd17102013-06-20 11:21:49 +00001116int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1117
Vladimir Medic8cd17102013-06-20 11:21:49 +00001118 int CC;
1119 CC = matchCPURegisterName(Name);
1120 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001121 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1122 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001123 CC = matchFPURegisterName(Name);
Vladimir Medic4c299852013-11-06 11:27:05 +00001124 // TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001125 if (CC != -1)
1126 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1127 : Mips::FGR32RegClassID);
1128 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001129}
1130
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001131int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001132
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001133 switch (RegKind) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001134 case MipsOperand::Kind_GPR32:
1135 return Mips::GPR32RegClassID;
1136 case MipsOperand::Kind_GPR64:
1137 return Mips::GPR64RegClassID;
1138 case MipsOperand::Kind_HWRegs:
1139 return Mips::HWRegsRegClassID;
1140 case MipsOperand::Kind_FGR32Regs:
1141 return Mips::FGR32RegClassID;
1142 case MipsOperand::Kind_FGRH32Regs:
1143 return Mips::FGRH32RegClassID;
1144 case MipsOperand::Kind_FGR64Regs:
1145 return Mips::FGR64RegClassID;
1146 case MipsOperand::Kind_AFGR64Regs:
1147 return Mips::AFGR64RegClassID;
1148 case MipsOperand::Kind_CCRRegs:
1149 return Mips::CCRRegClassID;
1150 case MipsOperand::Kind_ACC64DSP:
1151 return Mips::ACC64DSPRegClassID;
1152 case MipsOperand::Kind_FCCRegs:
1153 return Mips::FCCRegClassID;
1154 case MipsOperand::Kind_MSA128BRegs:
1155 return Mips::MSA128BRegClassID;
1156 case MipsOperand::Kind_MSA128HRegs:
1157 return Mips::MSA128HRegClassID;
1158 case MipsOperand::Kind_MSA128WRegs:
1159 return Mips::MSA128WRegClassID;
1160 case MipsOperand::Kind_MSA128DRegs:
1161 return Mips::MSA128DRegClassID;
1162 case MipsOperand::Kind_MSA128CtrlRegs:
1163 return Mips::MSACtrlRegClassID;
1164 default:
1165 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001166 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001167}
Jack Carterb4dbc172012-09-05 23:34:03 +00001168
Jack Carter0b744b32012-10-04 02:29:46 +00001169bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1170 if (Reg > 31)
1171 return false;
1172
1173 aTReg = Reg;
1174 return true;
1175}
1176
Vladimir Medic4c299852013-11-06 11:27:05 +00001177int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
Jack Carter0b744b32012-10-04 02:29:46 +00001178
Jack Carterd0bd6422013-04-18 00:41:53 +00001179unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001180 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001181}
1182
Jack Carter873c7242013-01-12 01:03:14 +00001183int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001184 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001185 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001186 return -1;
1187
Jack Carter873c7242013-01-12 01:03:14 +00001188 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001189}
1190
Jack Carter873c7242013-01-12 01:03:14 +00001191int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001192 const AsmToken &Tok = Parser.getTok();
1193 int RegNum = -1;
1194
1195 if (Tok.is(AsmToken::Identifier)) {
1196 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001197 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001198 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001199 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001200 is64BitReg ? Mips::GPR64RegClassID
1201 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001202 return RegNum;
1203}
1204
Jack Carterd0bd6422013-04-18 00:41:53 +00001205bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001206 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001207
1208 SMLoc S = Parser.getTok().getLoc();
1209 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001210
Jack Carter873c7242013-01-12 01:03:14 +00001211 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001212 if (RegNo == -1)
1213 return true;
1214
Vladimir Medic4c299852013-11-06 11:27:05 +00001215 Operands.push_back(
1216 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001217 Parser.Lex(); // Eat register token.
1218 return false;
1219}
1220
Vladimir Medic4c299852013-11-06 11:27:05 +00001221bool
1222MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1223 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001224 // Check if the current operand has a custom associated parser, if so, try to
1225 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001226 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1227 if (ResTy == MatchOperand_Success)
1228 return false;
1229 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1230 // there was a match, but an error occurred, in which case, just return that
1231 // the operand parsing failed.
1232 if (ResTy == MatchOperand_ParseFail)
1233 return true;
1234
1235 switch (getLexer().getKind()) {
1236 default:
1237 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1238 return true;
1239 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001240 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001241 SMLoc S = Parser.getTok().getLoc();
1242 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001243 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001244 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001245 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001246 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001247 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001248 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001249 if (getLexer().isNot(AsmToken::Dollar))
1250 return true;
1251
Jack Carterd0bd6422013-04-18 00:41:53 +00001252 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001253 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001254 return true;
1255
1256 if (!getLexer().is(AsmToken::RParen))
1257 return true;
1258
1259 S = Parser.getTok().getLoc();
1260 Operands.push_back(MipsOperand::CreateToken(")", S));
1261 Parser.Lex();
1262 }
1263 return false;
1264 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001265 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001266 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001267 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001268 return true;
1269
Jack Carter873c7242013-01-12 01:03:14 +00001270 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001271 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001272 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001273 const MCExpr *Res =
1274 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001275
1276 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1277 return false;
1278 }
1279 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001280 // For instruction aliases like "bc1f $Label" dedicated parser will
1281 // eat the '$' sign before failing. So in order to look for appropriate
1282 // label we must check first if we have already consumed '$'.
1283 if (hasConsumedDollar) {
1284 hasConsumedDollar = false;
1285 SMLoc S = Parser.getTok().getLoc();
1286 StringRef Identifier;
1287 if (Parser.parseIdentifier(Identifier))
1288 return true;
1289 SMLoc E =
1290 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1291 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1292 // Create a symbol reference.
1293 const MCExpr *Res =
1294 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1295
1296 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1297 return false;
1298 }
Jack Carterd76b2372013-03-21 21:44:16 +00001299 // Look for the existing symbol, we should check if
Matheus Almeidad534fc32014-01-30 13:40:26 +00001300 // we need to assign the proper RegisterKind.
Jack Carterd0bd6422013-04-18 00:41:53 +00001301 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1302 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001303 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001304 case AsmToken::LParen:
1305 case AsmToken::Minus:
1306 case AsmToken::Plus:
1307 case AsmToken::Integer:
1308 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001309 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001310 const MCExpr *IdVal;
1311 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001312 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001313 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001314 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001315 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1316 return false;
1317 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001318 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001319 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001320 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001321 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001322 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001323 return true;
1324
Jack Carter873c7242013-01-12 01:03:14 +00001325 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1326
Jack Carterdc1e35d2012-09-06 20:00:02 +00001327 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1328 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001329 } // case AsmToken::Percent
1330 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001331 return true;
1332}
1333
Vladimir Medic4c299852013-11-06 11:27:05 +00001334const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001335 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001336 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001337 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001338 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001339 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001340 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001341 short Val = MCE->getValue();
1342 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001343 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001344 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001345 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001346 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001347 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001348 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001349 if (LoSign)
1350 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001351 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001352 } else {
1353 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001354 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001355 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001356 }
1357
Jack Carterb5cf5902013-04-17 00:18:04 +00001358 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001359 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001360 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001361 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001362 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001363 return Res;
1364 }
1365
1366 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001367 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1368
1369 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1370 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1371 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1372 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1373 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1374 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1375 return MipsMCExpr::CreateHi(Expr, getContext());
1376 return MipsMCExpr::CreateLo(Expr, getContext());
1377 }
1378
Jack Carterd0bd6422013-04-18 00:41:53 +00001379 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1380 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001381 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1382 return Res;
1383 }
1384
1385 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001386 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1387 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1388 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001389 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001390 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001391 return Expr;
1392}
1393
1394bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1395
1396 switch (Expr->getKind()) {
1397 case MCExpr::Constant:
1398 return true;
1399 case MCExpr::SymbolRef:
1400 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1401 case MCExpr::Binary:
1402 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1403 if (!isEvaluated(BE->getLHS()))
1404 return false;
1405 return isEvaluated(BE->getRHS());
1406 }
1407 case MCExpr::Unary:
1408 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001409 case MCExpr::Target:
1410 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001411 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001412 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001413}
Jack Carterd0bd6422013-04-18 00:41:53 +00001414
Jack Carterb5cf5902013-04-17 00:18:04 +00001415bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001416 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001417 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001418 if (Tok.isNot(AsmToken::Identifier))
1419 return true;
1420
1421 std::string Str = Tok.getIdentifier().str();
1422
Jack Carterd0bd6422013-04-18 00:41:53 +00001423 Parser.Lex(); // Eat the identifier.
1424 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001425 const MCExpr *IdVal;
1426 SMLoc EndLoc;
1427
1428 if (getLexer().getKind() == AsmToken::LParen) {
1429 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001430 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001431 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001432 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001433 const AsmToken &nextTok = Parser.getTok();
1434 if (nextTok.isNot(AsmToken::Identifier))
1435 return true;
1436 Str += "(%";
1437 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001438 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001439 if (getLexer().getKind() != AsmToken::LParen)
1440 return true;
1441 } else
1442 break;
1443 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001444 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001445 return true;
1446
1447 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001448 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001449
1450 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001451 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001452
Jack Carterd0bd6422013-04-18 00:41:53 +00001453 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001454 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001455}
1456
Jack Carterb4dbc172012-09-05 23:34:03 +00001457bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1458 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001459 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001460 RegNo = tryParseRegister(isMips64());
1461 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001462 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001463}
1464
Jack Carterb5cf5902013-04-17 00:18:04 +00001465bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001466 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001467 bool Result = true;
1468
1469 while (getLexer().getKind() == AsmToken::LParen)
1470 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001471
Jack Carterd0bd6422013-04-18 00:41:53 +00001472 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001473 default:
1474 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001475 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001476 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001477 case AsmToken::Integer:
1478 case AsmToken::Minus:
1479 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001480 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001481 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001482 else
1483 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001484 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001485 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001486 break;
Jack Carter873c7242013-01-12 01:03:14 +00001487 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001488 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001489 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001490 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001491}
1492
Jack Carterb4dbc172012-09-05 23:34:03 +00001493MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001494 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001495
1496 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001497 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001498 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001499 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001500 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001501 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001502
Jack Carterb5cf5902013-04-17 00:18:04 +00001503 if (getLexer().getKind() == AsmToken::LParen) {
1504 Parser.Lex();
1505 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001506 }
1507
Jack Carterb5cf5902013-04-17 00:18:04 +00001508 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001509 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001510 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001511
Jack Carterd0bd6422013-04-18 00:41:53 +00001512 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001513 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001514 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001515 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001516 SMLoc E =
1517 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001518 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1519 return MatchOperand_Success;
1520 }
1521 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001522 SMLoc E =
1523 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001524
Jack Carterd0bd6422013-04-18 00:41:53 +00001525 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001526 Operands.push_back(MipsOperand::CreateMem(
1527 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001528 return MatchOperand_Success;
1529 }
1530 Error(Parser.getTok().getLoc(), "'(' expected");
1531 return MatchOperand_ParseFail;
1532 }
1533
Jack Carterd0bd6422013-04-18 00:41:53 +00001534 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001535 }
1536
Vladimir Medic4c299852013-11-06 11:27:05 +00001537 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1538 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001539 if (Res != MatchOperand_Success)
1540 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001541
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001542 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001543 Error(Parser.getTok().getLoc(), "')' expected");
1544 return MatchOperand_ParseFail;
1545 }
1546
Jack Carter873c7242013-01-12 01:03:14 +00001547 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1548
Jack Carterd0bd6422013-04-18 00:41:53 +00001549 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001550
1551 if (IdVal == 0)
1552 IdVal = MCConstantExpr::Create(0, getContext());
1553
Jack Carterd0bd6422013-04-18 00:41:53 +00001554 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001555 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001556 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001557 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001558 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001559 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001560 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1561 int64_t Imm;
1562 if (IdVal->EvaluateAsAbsolute(Imm))
1563 IdVal = MCConstantExpr::Create(Imm, getContext());
1564 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1565 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1566 getContext());
1567 }
1568
Jack Carterdc1e35d2012-09-06 20:00:02 +00001569 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1570 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001571 return MatchOperand_Success;
1572}
1573
Vladimir Medic4c299852013-11-06 11:27:05 +00001574bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1575 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001576 // If the first token is not '$' we have an error.
1577 if (Parser.getTok().isNot(AsmToken::Dollar))
1578 return false;
1579
1580 SMLoc S = Parser.getTok().getLoc();
1581 Parser.Lex();
1582 AsmToken::TokenKind TkKind = getLexer().getKind();
1583 int Reg;
1584
1585 if (TkKind == AsmToken::Integer) {
1586 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1587 regKindToRegClass(RegKind));
1588 if (Reg == -1)
1589 return false;
1590 } else if (TkKind == AsmToken::Identifier) {
1591 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1592 return false;
1593 Reg = getReg(regKindToRegClass(RegKind), Reg);
1594 } else {
1595 return false;
1596 }
1597
1598 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1599 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1600 Operands.push_back(Op);
1601 Parser.Lex();
1602 return true;
1603}
1604
1605MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001606MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1607 MipsOperand::RegisterKind RegKind =
1608 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001609
1610 // Parse index register.
1611 if (!parsePtrReg(Operands, RegKind))
1612 return MatchOperand_NoMatch;
1613
1614 // Parse '('.
1615 if (Parser.getTok().isNot(AsmToken::LParen))
1616 return MatchOperand_NoMatch;
1617
1618 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1619 Parser.Lex();
1620
1621 // Parse base register.
1622 if (!parsePtrReg(Operands, RegKind))
1623 return MatchOperand_NoMatch;
1624
1625 // Parse ')'.
1626 if (Parser.getTok().isNot(AsmToken::RParen))
1627 return MatchOperand_NoMatch;
1628
1629 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1630 Parser.Lex();
1631
1632 return MatchOperand_Success;
1633}
1634
Jack Carter873c7242013-01-12 01:03:14 +00001635MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001636MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001637 int RegKind) {
1638 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001639 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001640 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001641 return MatchOperand_Success;
1642 return MatchOperand_NoMatch;
1643 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001644 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001645 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001646 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001647 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001648 if (!hasConsumedDollar) {
1649 Parser.Lex(); // Eat the '$'
1650 hasConsumedDollar = true;
1651 }
1652 if (getLexer().getKind() == AsmToken::Identifier) {
1653 int RegNum = -1;
1654 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001655 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001656 switch (RegKind) {
1657 case MipsOperand::Kind_GPR32:
1658 case MipsOperand::Kind_GPR64:
1659 RegNum = matchCPURegisterName(RegName);
1660 break;
1661 case MipsOperand::Kind_AFGR64Regs:
1662 case MipsOperand::Kind_FGR64Regs:
1663 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001664 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001665 RegNum = matchFPURegisterName(RegName);
1666 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1667 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001668 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1669 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001670 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001671 break;
1672 case MipsOperand::Kind_FCCRegs:
1673 RegNum = matchFCCRegisterName(RegName);
1674 break;
1675 case MipsOperand::Kind_ACC64DSP:
1676 RegNum = matchACRegisterName(RegName);
1677 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001678 default:
1679 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001680 }
1681 // No match found, return _NoMatch to give a chance to other round.
1682 if (RegNum < 0)
1683 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001684
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001685 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1686 if (RegVal == -1)
1687 return MatchOperand_NoMatch;
1688
Vladimir Medic4c299852013-11-06 11:27:05 +00001689 MipsOperand *Op =
1690 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001691 Op->setRegKind(Kind);
1692 Operands.push_back(Op);
1693 hasConsumedDollar = false;
1694 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001695 return MatchOperand_Success;
1696 } else if (getLexer().getKind() == AsmToken::Integer) {
1697 unsigned RegNum = Parser.getTok().getIntVal();
1698 if (Kind == MipsOperand::Kind_HWRegs) {
1699 if (RegNum != 29)
1700 return MatchOperand_NoMatch;
1701 // Only hwreg 29 is supported, found at index 0.
1702 RegNum = 0;
1703 }
1704 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1705 if (Reg == -1)
1706 return MatchOperand_NoMatch;
1707 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1708 Op->setRegKind(Kind);
1709 Operands.push_back(Op);
1710 hasConsumedDollar = false;
1711 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001712 if ((RegKind == MipsOperand::Kind_GPR32) &&
1713 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001714 // Check if it is indexed addressing operand.
1715 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1716 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001717 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001718 return MatchOperand_NoMatch;
1719 if (getLexer().isNot(AsmToken::RParen))
1720 return MatchOperand_NoMatch;
1721 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1722 Parser.Lex();
1723 }
Jack Carter873c7242013-01-12 01:03:14 +00001724 return MatchOperand_Success;
1725 }
1726 return MatchOperand_NoMatch;
1727}
Vladimir Medic64828a12013-07-16 10:07:14 +00001728
Matheus Almeidab74293d2013-10-14 11:49:30 +00001729bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1730 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1731
1732 if (Val < 0)
1733 return false;
1734
1735 switch (Kind) {
1736 default:
1737 return false;
1738 case MipsOperand::Kind_MSA128BRegs:
1739 return Val < 16;
1740 case MipsOperand::Kind_MSA128HRegs:
1741 return Val < 8;
1742 case MipsOperand::Kind_MSA128WRegs:
1743 return Val < 4;
1744 case MipsOperand::Kind_MSA128DRegs:
1745 return Val < 2;
1746 }
1747}
1748
Vladimir Medic8cd17102013-06-20 11:21:49 +00001749MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001750MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001751 int RegKind) {
1752 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1753 SMLoc S = Parser.getTok().getLoc();
1754 std::string RegName;
1755
1756 if (Parser.getTok().isNot(AsmToken::Dollar))
1757 return MatchOperand_NoMatch;
1758
1759 switch (RegKind) {
1760 default:
1761 return MatchOperand_ParseFail;
1762 case MipsOperand::Kind_MSA128BRegs:
1763 case MipsOperand::Kind_MSA128HRegs:
1764 case MipsOperand::Kind_MSA128WRegs:
1765 case MipsOperand::Kind_MSA128DRegs:
1766 break;
1767 }
1768
1769 Parser.Lex(); // Eat the '$'.
1770 if (getLexer().getKind() == AsmToken::Identifier)
1771 RegName = Parser.getTok().getString().lower();
1772 else
1773 return MatchOperand_ParseFail;
1774
1775 int RegNum = matchMSA128RegisterName(RegName);
1776
1777 if (RegNum < 0 || RegNum > 31)
1778 return MatchOperand_ParseFail;
1779
1780 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1781 if (RegVal == -1)
1782 return MatchOperand_ParseFail;
1783
Vladimir Medic4c299852013-11-06 11:27:05 +00001784 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001785 Op->setRegKind(Kind);
1786 Operands.push_back(Op);
1787
1788 Parser.Lex(); // Eat the register identifier.
1789
Matheus Almeidab74293d2013-10-14 11:49:30 +00001790 // MSA registers may be suffixed with an index in the form of:
1791 // 1) Immediate expression.
1792 // 2) General Purpose Register.
1793 // Examples:
1794 // 1) copy_s.b $29,$w0[0]
1795 // 2) sld.b $w0,$w1[$1]
1796
1797 if (Parser.getTok().isNot(AsmToken::LBrac))
1798 return MatchOperand_Success;
1799
1800 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1801
1802 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1803 Parser.Lex(); // Parse the '[' token.
1804
1805 if (Parser.getTok().is(AsmToken::Dollar)) {
1806 // This must be a GPR.
1807 MipsOperand *RegOp;
1808 SMLoc VIdx = Parser.getTok().getLoc();
1809 Parser.Lex(); // Parse the '$' token.
1810
1811 // GPR have aliases and we must account for that. Example: $30 == $fp
1812 if (getLexer().getKind() == AsmToken::Integer) {
1813 unsigned RegNum = Parser.getTok().getIntVal();
1814 int Reg = matchRegisterByNumber(
1815 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1816 if (Reg == -1) {
1817 Error(VIdx, "invalid general purpose register");
1818 return MatchOperand_ParseFail;
1819 }
1820
1821 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1822 } else if (getLexer().getKind() == AsmToken::Identifier) {
1823 int RegNum = -1;
1824 std::string RegName = Parser.getTok().getString().lower();
1825
1826 RegNum = matchCPURegisterName(RegName);
1827 if (RegNum == -1) {
1828 Error(VIdx, "general purpose register expected");
1829 return MatchOperand_ParseFail;
1830 }
1831 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1832 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1833 } else
1834 return MatchOperand_ParseFail;
1835
1836 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1837 Operands.push_back(RegOp);
1838 Parser.Lex(); // Eat the register identifier.
1839
1840 if (Parser.getTok().isNot(AsmToken::RBrac))
1841 return MatchOperand_ParseFail;
1842
1843 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1844 Parser.Lex(); // Parse the ']' token.
1845
1846 return MatchOperand_Success;
1847 }
1848
1849 // The index must be a constant expression then.
1850 SMLoc VIdx = Parser.getTok().getLoc();
1851 const MCExpr *ImmVal;
1852
1853 if (getParser().parseExpression(ImmVal))
1854 return MatchOperand_ParseFail;
1855
1856 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1857 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1858 Error(VIdx, "invalid immediate value");
1859 return MatchOperand_ParseFail;
1860 }
1861
1862 SMLoc E = Parser.getTok().getEndLoc();
1863
1864 if (Parser.getTok().isNot(AsmToken::RBrac))
1865 return MatchOperand_ParseFail;
1866
Vladimir Medic4c299852013-11-06 11:27:05 +00001867 bool insve =
1868 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1869 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001870
1871 // The second vector index of insve instructions is always 0.
1872 if (insve && Operands.size() > 6) {
1873 if (expr->getValue() != 0) {
1874 Error(VIdx, "immediate value must be 0");
1875 return MatchOperand_ParseFail;
1876 }
1877 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1878 } else
1879 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1880
1881 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1882
1883 Parser.Lex(); // Parse the ']' token.
1884
Jack Carter5dc8ac92013-09-25 23:50:44 +00001885 return MatchOperand_Success;
1886}
1887
1888MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001889MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1890 int RegKind) {
1891 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1892
1893 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1894 return MatchOperand_NoMatch;
1895
1896 if (Parser.getTok().isNot(AsmToken::Dollar))
1897 return MatchOperand_ParseFail;
1898
1899 SMLoc S = Parser.getTok().getLoc();
1900
1901 Parser.Lex(); // Eat the '$' symbol.
1902
1903 int RegNum = -1;
1904 if (getLexer().getKind() == AsmToken::Identifier)
1905 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1906 else if (getLexer().getKind() == AsmToken::Integer)
1907 RegNum = Parser.getTok().getIntVal();
1908 else
1909 return MatchOperand_ParseFail;
1910
1911 if (RegNum < 0 || RegNum > 7)
1912 return MatchOperand_ParseFail;
1913
1914 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1915 if (RegVal == -1)
1916 return MatchOperand_ParseFail;
1917
Vladimir Medic4c299852013-11-06 11:27:05 +00001918 MipsOperand *RegOp =
1919 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001920 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1921 Operands.push_back(RegOp);
1922 Parser.Lex(); // Eat the register identifier.
1923
1924 return MatchOperand_Success;
1925}
1926
1927MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001928MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001929
1930 if (!isMips64())
1931 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001932 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001933}
1934
1935MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001936MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1937 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001938}
Jack Carter873c7242013-01-12 01:03:14 +00001939
Vladimir Medic4c299852013-11-06 11:27:05 +00001940MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1941 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001942
1943 if (isFP64())
1944 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001945 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001946}
1947
1948MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001949MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001950 if (!isFP64())
1951 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001952 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001953}
1954
1955MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001956MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1957 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1958}
1959
1960MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1961 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1962 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001963}
1964
Vladimir Medic643b3982013-07-30 10:12:14 +00001965MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001966MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1967 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001968}
1969
1970MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001971MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1972 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001973}
1974
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001975MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001976MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001977 // If the first token is not '$' we have an error.
1978 if (Parser.getTok().isNot(AsmToken::Dollar))
1979 return MatchOperand_NoMatch;
1980
1981 SMLoc S = Parser.getTok().getLoc();
1982 Parser.Lex(); // Eat the '$'
1983
1984 const AsmToken &Tok = Parser.getTok(); // Get next token.
1985
1986 if (Tok.isNot(AsmToken::Identifier))
1987 return MatchOperand_NoMatch;
1988
1989 if (!Tok.getIdentifier().startswith("ac"))
1990 return MatchOperand_NoMatch;
1991
1992 StringRef NumString = Tok.getIdentifier().substr(2);
1993
1994 unsigned IntVal;
1995 if (NumString.getAsInteger(10, IntVal))
1996 return MatchOperand_NoMatch;
1997
1998 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1999
2000 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2001 Op->setRegKind(MipsOperand::Kind_LO32DSP);
2002 Operands.push_back(Op);
2003
2004 Parser.Lex(); // Eat the register number.
2005 return MatchOperand_Success;
2006}
2007
2008MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002009MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00002010 // If the first token is not '$' we have an error.
2011 if (Parser.getTok().isNot(AsmToken::Dollar))
2012 return MatchOperand_NoMatch;
2013
2014 SMLoc S = Parser.getTok().getLoc();
2015 Parser.Lex(); // Eat the '$'
2016
2017 const AsmToken &Tok = Parser.getTok(); // Get next token.
2018
2019 if (Tok.isNot(AsmToken::Identifier))
2020 return MatchOperand_NoMatch;
2021
2022 if (!Tok.getIdentifier().startswith("ac"))
2023 return MatchOperand_NoMatch;
2024
2025 StringRef NumString = Tok.getIdentifier().substr(2);
2026
2027 unsigned IntVal;
2028 if (NumString.getAsInteger(10, IntVal))
2029 return MatchOperand_NoMatch;
2030
2031 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
2032
2033 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2034 Op->setRegKind(MipsOperand::Kind_HI32DSP);
2035 Operands.push_back(Op);
2036
2037 Parser.Lex(); // Eat the register number.
2038 return MatchOperand_Success;
2039}
2040
Vladimir Medic05bcde62013-09-16 10:29:42 +00002041MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002042MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00002043 // If the first token is not '$' we have an error.
2044 if (Parser.getTok().isNot(AsmToken::Dollar))
2045 return MatchOperand_NoMatch;
2046
2047 SMLoc S = Parser.getTok().getLoc();
2048 Parser.Lex(); // Eat the '$'
2049
2050 const AsmToken &Tok = Parser.getTok(); // Get next token.
2051
2052 if (Tok.isNot(AsmToken::Integer))
2053 return MatchOperand_NoMatch;
2054
2055 unsigned IntVal = Tok.getIntVal();
2056
2057 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2058
2059 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2060 Op->setRegKind(MipsOperand::Kind_COP2);
2061 Operands.push_back(Op);
2062
2063 Parser.Lex(); // Eat the register number.
2064 return MatchOperand_Success;
2065}
2066
Vladimir Medic4c299852013-11-06 11:27:05 +00002067MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2068 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2069 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002070}
2071
Vladimir Medic4c299852013-11-06 11:27:05 +00002072MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2073 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2074 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002075}
2076
Vladimir Medic4c299852013-11-06 11:27:05 +00002077MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2078 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2079 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002080}
2081
Vladimir Medic4c299852013-11-06 11:27:05 +00002082MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2083 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2084 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002085}
2086
Vladimir Medic4c299852013-11-06 11:27:05 +00002087MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2088 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2089 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002090}
2091
Jack Carterd0bd6422013-04-18 00:41:53 +00002092bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002093 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002094
2095 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2096 if (Sym) {
2097 SMLoc S = Parser.getTok().getLoc();
2098 const MCExpr *Expr;
2099 if (Sym->isVariable())
2100 Expr = Sym->getVariableValue();
2101 else
2102 return false;
2103 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002104 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2105 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002106 const StringRef DefSymbol = Ref->getSymbol().getName();
2107 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002108 int RegNum = -1;
2109 APInt IntVal(32, -1);
2110 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2111 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002112 isMips64() ? Mips::GPR64RegClassID
2113 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002114 else {
2115 // Lookup for the register with the corresponding name.
2116 switch (Kind) {
2117 case MipsOperand::Kind_AFGR64Regs:
2118 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002119 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002120 break;
2121 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002122 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002123 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002124 case MipsOperand::Kind_GPR64:
2125 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002126 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002127 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002128 break;
2129 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002130 if (RegNum > -1)
2131 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002132 }
Jack Carterd76b2372013-03-21 21:44:16 +00002133 if (RegNum > -1) {
2134 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002135 MipsOperand *op =
2136 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002137 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002138 Operands.push_back(op);
2139 return true;
2140 }
2141 }
2142 } else if (Expr->getKind() == MCExpr::Constant) {
2143 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002144 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2145 MipsOperand *op =
2146 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002147 Operands.push_back(op);
2148 return true;
2149 }
2150 }
2151 return false;
2152}
Jack Carterd0bd6422013-04-18 00:41:53 +00002153
Jack Carter873c7242013-01-12 01:03:14 +00002154MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002155MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2156 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002157}
2158
2159MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002160MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2161 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002162}
2163
Vladimir Medic2b953d02013-10-01 09:48:56 +00002164MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002165MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002166 const MCExpr *IdVal;
2167 // If the first token is '$' we may have register operand.
2168 if (Parser.getTok().is(AsmToken::Dollar))
2169 return MatchOperand_NoMatch;
2170 SMLoc S = Parser.getTok().getLoc();
2171 if (getParser().parseExpression(IdVal))
2172 return MatchOperand_ParseFail;
2173 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002174 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002175 int64_t Val = MCE->getValue();
2176 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2177 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002178 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002179 return MatchOperand_Success;
2180}
2181
Matheus Almeida779c5932013-11-18 12:32:49 +00002182MipsAsmParser::OperandMatchResultTy
2183MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2184 switch (getLexer().getKind()) {
2185 default:
2186 return MatchOperand_NoMatch;
2187 case AsmToken::LParen:
2188 case AsmToken::Plus:
2189 case AsmToken::Minus:
2190 case AsmToken::Integer:
2191 break;
2192 }
2193
2194 const MCExpr *Expr;
2195 SMLoc S = Parser.getTok().getLoc();
2196
2197 if (getParser().parseExpression(Expr))
2198 return MatchOperand_ParseFail;
2199
2200 int64_t Val;
2201 if (!Expr->EvaluateAsAbsolute(Val)) {
2202 Error(S, "expected immediate value");
2203 return MatchOperand_ParseFail;
2204 }
2205
2206 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2207 // and because the CPU always adds one to the immediate field, the allowed
2208 // range becomes 1..4. We'll only check the range here and will deal
2209 // with the addition/subtraction when actually decoding/encoding
2210 // the instruction.
2211 if (Val < 1 || Val > 4) {
2212 Error(S, "immediate not in range (1..4)");
2213 return MatchOperand_ParseFail;
2214 }
2215
Jack Carter3b2c96e2014-01-22 23:31:38 +00002216 Operands.push_back(
2217 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002218 return MatchOperand_Success;
2219}
2220
Jack Carterdc1e35d2012-09-06 20:00:02 +00002221MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2222
Vladimir Medic4c299852013-11-06 11:27:05 +00002223 MCSymbolRefExpr::VariantKind VK =
2224 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2225 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2226 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2227 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2228 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2229 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2230 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2231 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2232 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2233 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2234 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2235 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2236 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2237 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2238 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2239 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2240 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2241 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2242 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002243
2244 return VK;
2245}
Jack Cartera63b16a2012-09-07 00:23:42 +00002246
Vladimir Medic4c299852013-11-06 11:27:05 +00002247bool MipsAsmParser::ParseInstruction(
2248 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2249 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002250 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002251 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002252 Parser.eatToEndOfStatement();
2253 return Error(NameLoc, "Unknown instruction");
2254 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002255 // First operand in MCInst is instruction mnemonic.
2256 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002257
2258 // Read the remaining operands.
2259 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2260 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002261 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002262 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002263 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002264 return Error(Loc, "unexpected token in argument list");
2265 }
2266
Jack Carterd0bd6422013-04-18 00:41:53 +00002267 while (getLexer().is(AsmToken::Comma)) {
2268 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002269 // Parse and remember the operand.
2270 if (ParseOperand(Operands, Name)) {
2271 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002272 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002273 return Error(Loc, "unexpected token in argument list");
2274 }
2275 }
2276 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002277 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2278 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002279 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002280 return Error(Loc, "unexpected token in argument list");
2281 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002282 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002283 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002284}
2285
Jack Carter0b744b32012-10-04 02:29:46 +00002286bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002287 SMLoc Loc = getLexer().getLoc();
2288 Parser.eatToEndOfStatement();
2289 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002290}
2291
2292bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002293 // Line should look like: ".set noat".
2294 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002295 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002296 // eat noat
2297 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002298 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002299 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2300 reportParseError("unexpected token in statement");
2301 return false;
2302 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002303 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002304 return false;
2305}
Jack Carterd0bd6422013-04-18 00:41:53 +00002306
Jack Carter0b744b32012-10-04 02:29:46 +00002307bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002308 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002309 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002310 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002311 getParser().Lex();
2312 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002313 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002314 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002315 return false;
2316 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002317 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002318 if (getLexer().isNot(AsmToken::Dollar)) {
2319 reportParseError("unexpected token in statement");
2320 return false;
2321 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002322 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002323 const AsmToken &Reg = Parser.getTok();
2324 if (Reg.is(AsmToken::Identifier)) {
2325 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2326 } else if (Reg.is(AsmToken::Integer)) {
2327 AtRegNo = Reg.getIntVal();
2328 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002329 reportParseError("unexpected token in statement");
2330 return false;
2331 }
Jack Carter1ac53222013-02-20 23:11:17 +00002332
Jack Carterd0bd6422013-04-18 00:41:53 +00002333 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002334 reportParseError("unexpected token in statement");
2335 return false;
2336 }
2337
2338 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002339 reportParseError("unexpected token in statement");
2340 return false;
2341 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002342 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002343
2344 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2345 reportParseError("unexpected token in statement");
2346 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002347 }
2348 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002349 return false;
2350 } else {
2351 reportParseError("unexpected token in statement");
2352 return false;
2353 }
2354}
2355
2356bool MipsAsmParser::parseSetReorderDirective() {
2357 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002358 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2360 reportParseError("unexpected token in statement");
2361 return false;
2362 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002363 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002364 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002365 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002366 return false;
2367}
2368
2369bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002370 Parser.Lex();
2371 // If this is not the end of the statement, report an error.
2372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2373 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002374 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002375 }
2376 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002377 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002378 Parser.Lex(); // Consume the EndOfStatement.
2379 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002380}
2381
2382bool MipsAsmParser::parseSetMacroDirective() {
2383 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002384 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2386 reportParseError("unexpected token in statement");
2387 return false;
2388 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002389 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002390 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002391 return false;
2392}
2393
2394bool MipsAsmParser::parseSetNoMacroDirective() {
2395 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002396 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2398 reportParseError("`noreorder' must be set before `nomacro'");
2399 return false;
2400 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002401 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002402 reportParseError("`noreorder' must be set before `nomacro'");
2403 return false;
2404 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002405 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002406 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002407 return false;
2408}
Jack Carterd76b2372013-03-21 21:44:16 +00002409
Jack Carter39536722014-01-22 23:08:42 +00002410bool MipsAsmParser::parseSetMips16Directive() {
2411 Parser.Lex();
2412 // If this is not the end of the statement, report an error.
2413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2414 reportParseError("unexpected token in statement");
2415 return false;
2416 }
Rafael Espindolae7583752014-01-24 16:13:20 +00002417 getTargetStreamer().emitDirectiveSetMips16();
Jack Carter39536722014-01-22 23:08:42 +00002418 Parser.Lex(); // Consume the EndOfStatement.
2419 return false;
2420}
2421
2422bool MipsAsmParser::parseSetNoMips16Directive() {
2423 Parser.Lex();
2424 // If this is not the end of the statement, report an error.
2425 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2426 reportParseError("unexpected token in statement");
2427 return false;
2428 }
2429 // For now do nothing.
2430 Parser.Lex(); // Consume the EndOfStatement.
2431 return false;
2432}
2433
Jack Carterd76b2372013-03-21 21:44:16 +00002434bool MipsAsmParser::parseSetAssignment() {
2435 StringRef Name;
2436 const MCExpr *Value;
2437
2438 if (Parser.parseIdentifier(Name))
2439 reportParseError("expected identifier after .set");
2440
2441 if (getLexer().isNot(AsmToken::Comma))
2442 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002443 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002444
Jack Carter3b2c96e2014-01-22 23:31:38 +00002445 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002446 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002447
Jack Carterd0bd6422013-04-18 00:41:53 +00002448 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002449 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002450 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002451 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002452 Sym = getContext().GetOrCreateSymbol(Name);
2453 Sym->setVariableValue(Value);
2454
2455 return false;
2456}
Jack Carterd0bd6422013-04-18 00:41:53 +00002457
Jack Carter0b744b32012-10-04 02:29:46 +00002458bool MipsAsmParser::parseDirectiveSet() {
2459
Jack Carterd0bd6422013-04-18 00:41:53 +00002460 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002461 const AsmToken &Tok = Parser.getTok();
2462
2463 if (Tok.getString() == "noat") {
2464 return parseSetNoAtDirective();
2465 } else if (Tok.getString() == "at") {
2466 return parseSetAtDirective();
2467 } else if (Tok.getString() == "reorder") {
2468 return parseSetReorderDirective();
2469 } else if (Tok.getString() == "noreorder") {
2470 return parseSetNoReorderDirective();
2471 } else if (Tok.getString() == "macro") {
2472 return parseSetMacroDirective();
2473 } else if (Tok.getString() == "nomacro") {
2474 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002475 } else if (Tok.getString() == "mips16") {
2476 return parseSetMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002477 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002478 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002479 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002480 getTargetStreamer().emitDirectiveSetNoMicroMips();
2481 Parser.eatToEndOfStatement();
2482 return false;
2483 } else if (Tok.getString() == "micromips") {
2484 getTargetStreamer().emitDirectiveSetMicroMips();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002485 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002486 return false;
Vladimir Medic615b26e2014-03-04 09:54:09 +00002487 } else if (Tok.getString() == "mips32r2") {
2488 Parser.Lex(); // Eat token.
2489 if (getLexer().isNot(AsmToken::EndOfStatement))
2490 return reportParseError("unexpected token in .set directive");
2491 setFeatureBits(Mips::FeatureMips32r2,"mips32r2");
2492 getTargetStreamer().emitDirectiveSetMips32R2();
2493 return false;
Vladimir Medic27c398e2014-03-05 11:05:09 +00002494 } else if (Tok.getString() == "dsp") {
2495 Parser.Lex(); // Eat token.
2496 if (getLexer().isNot(AsmToken::EndOfStatement))
2497 return reportParseError("unexpected token in .set directive");
2498 setFeatureBits(Mips::FeatureDSP, "dsp");
2499 getTargetStreamer().emitDirectiveSetDsp();
2500 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002501 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002502 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002503 parseSetAssignment();
2504 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002505 }
Jack Carter07c818d2013-01-25 01:31:34 +00002506
Jack Carter0b744b32012-10-04 02:29:46 +00002507 return true;
2508}
2509
Jack Carter07c818d2013-01-25 01:31:34 +00002510/// parseDirectiveWord
2511/// ::= .word [ expression (, expression)* ]
2512bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2514 for (;;) {
2515 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002516 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002517 return true;
2518
2519 getParser().getStreamer().EmitValue(Value, Size);
2520
2521 if (getLexer().is(AsmToken::EndOfStatement))
2522 break;
2523
2524 // FIXME: Improve diagnostic.
2525 if (getLexer().isNot(AsmToken::Comma))
2526 return Error(L, "unexpected token in directive");
2527 Parser.Lex();
2528 }
2529 }
2530
2531 Parser.Lex();
2532 return false;
2533}
2534
Vladimir Medic4c299852013-11-06 11:27:05 +00002535/// parseDirectiveGpWord
2536/// ::= .gpword local_sym
2537bool MipsAsmParser::parseDirectiveGpWord() {
2538 const MCExpr *Value;
2539 // EmitGPRel32Value requires an expression, so we are using base class
2540 // method to evaluate the expression.
2541 if (getParser().parseExpression(Value))
2542 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002543 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002544
Vladimir Medice10c1122013-11-13 13:18:04 +00002545 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002546 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002547 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002548 return false;
2549}
2550
Jack Carter0cd3c192014-01-06 23:27:31 +00002551bool MipsAsmParser::parseDirectiveOption() {
2552 // Get the option token.
2553 AsmToken Tok = Parser.getTok();
2554 // At the moment only identifiers are supported.
2555 if (Tok.isNot(AsmToken::Identifier)) {
2556 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2557 Parser.eatToEndOfStatement();
2558 return false;
2559 }
2560
2561 StringRef Option = Tok.getIdentifier();
2562
2563 if (Option == "pic0") {
2564 getTargetStreamer().emitDirectiveOptionPic0();
2565 Parser.Lex();
2566 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2567 Error(Parser.getTok().getLoc(),
2568 "unexpected token in .option pic0 directive");
2569 Parser.eatToEndOfStatement();
2570 }
2571 return false;
2572 }
2573
2574 // Unknown option.
2575 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2576 Parser.eatToEndOfStatement();
2577 return false;
2578}
2579
Jack Carter0b744b32012-10-04 02:29:46 +00002580bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002581 StringRef IDVal = DirectiveID.getString();
2582
Jack Carterd0bd6422013-04-18 00:41:53 +00002583 if (IDVal == ".ent") {
2584 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002585 Parser.Lex();
2586 return false;
2587 }
2588
Jack Carter07c818d2013-01-25 01:31:34 +00002589 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002590 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002591 Parser.Lex();
2592 return false;
2593 }
2594
Jack Carter07c818d2013-01-25 01:31:34 +00002595 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002596 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002597 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002598 return false;
2599 }
2600
Jack Carter07c818d2013-01-25 01:31:34 +00002601 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002602 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002603 }
2604
Jack Carter07c818d2013-01-25 01:31:34 +00002605 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002606 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002607 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002608 return false;
2609 }
2610
Jack Carter07c818d2013-01-25 01:31:34 +00002611 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002612 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002613 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002614 return false;
2615 }
2616
Jack Carter07c818d2013-01-25 01:31:34 +00002617 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002618 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002619 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002620 return false;
2621 }
2622
Jack Carter07c818d2013-01-25 01:31:34 +00002623 if (IDVal == ".word") {
2624 parseDirectiveWord(4, DirectiveID.getLoc());
2625 return false;
2626 }
2627
Jack Carter0cd3c192014-01-06 23:27:31 +00002628 if (IDVal == ".option")
2629 return parseDirectiveOption();
2630
2631 if (IDVal == ".abicalls") {
2632 getTargetStreamer().emitDirectiveAbiCalls();
2633 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2634 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2635 // Clear line
2636 Parser.eatToEndOfStatement();
2637 }
2638 return false;
2639 }
2640
Rafael Espindola870c4e92012-01-11 03:56:41 +00002641 return true;
2642}
2643
Rafael Espindola870c4e92012-01-11 03:56:41 +00002644extern "C" void LLVMInitializeMipsAsmParser() {
2645 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2646 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2647 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2648 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2649}
Jack Carterb4dbc172012-09-05 23:34:03 +00002650
2651#define GET_REGISTER_MATCHER
2652#define GET_MATCHER_IMPLEMENTATION
2653#include "MipsGenAsmMatcher.inc"