blob: f54a62b666cf754c8235c504c0f921cae190fe0b [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
Daniel Sandersd89b1362014-03-24 16:48:01 +00001177int MipsAsmParser::getATReg() {
1178 int AT = Options.getATRegNum();
1179 if (AT == 0)
1180 TokError("Pseudo instruction requires $at, which is not available");
1181 return AT;
1182}
Jack Carter0b744b32012-10-04 02:29:46 +00001183
Jack Carterd0bd6422013-04-18 00:41:53 +00001184unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001185 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001186}
1187
Jack Carter873c7242013-01-12 01:03:14 +00001188int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001189 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001190 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001191 return -1;
1192
Jack Carter873c7242013-01-12 01:03:14 +00001193 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001194}
1195
Jack Carter873c7242013-01-12 01:03:14 +00001196int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001197 const AsmToken &Tok = Parser.getTok();
1198 int RegNum = -1;
1199
1200 if (Tok.is(AsmToken::Identifier)) {
1201 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001202 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001203 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001204 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001205 is64BitReg ? Mips::GPR64RegClassID
1206 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001207 return RegNum;
1208}
1209
Jack Carterd0bd6422013-04-18 00:41:53 +00001210bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001211 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001212
1213 SMLoc S = Parser.getTok().getLoc();
1214 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001215
Jack Carter873c7242013-01-12 01:03:14 +00001216 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001217 if (RegNo == -1)
1218 return true;
1219
Vladimir Medic4c299852013-11-06 11:27:05 +00001220 Operands.push_back(
1221 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001222 Parser.Lex(); // Eat register token.
1223 return false;
1224}
1225
Vladimir Medic4c299852013-11-06 11:27:05 +00001226bool
1227MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1228 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001229 // Check if the current operand has a custom associated parser, if so, try to
1230 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001231 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1232 if (ResTy == MatchOperand_Success)
1233 return false;
1234 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1235 // there was a match, but an error occurred, in which case, just return that
1236 // the operand parsing failed.
1237 if (ResTy == MatchOperand_ParseFail)
1238 return true;
1239
1240 switch (getLexer().getKind()) {
1241 default:
1242 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1243 return true;
1244 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001245 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001246 SMLoc S = Parser.getTok().getLoc();
1247 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001248 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001249 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001250 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001251 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001252 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001253 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001254 if (getLexer().isNot(AsmToken::Dollar))
1255 return true;
1256
Jack Carterd0bd6422013-04-18 00:41:53 +00001257 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001258 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001259 return true;
1260
1261 if (!getLexer().is(AsmToken::RParen))
1262 return true;
1263
1264 S = Parser.getTok().getLoc();
1265 Operands.push_back(MipsOperand::CreateToken(")", S));
1266 Parser.Lex();
1267 }
1268 return false;
1269 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001270 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001271 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001272 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001273 return true;
1274
Jack Carter873c7242013-01-12 01:03:14 +00001275 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001276 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001277 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001278 const MCExpr *Res =
1279 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001280
1281 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1282 return false;
1283 }
1284 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001285 // For instruction aliases like "bc1f $Label" dedicated parser will
1286 // eat the '$' sign before failing. So in order to look for appropriate
1287 // label we must check first if we have already consumed '$'.
1288 if (hasConsumedDollar) {
1289 hasConsumedDollar = false;
1290 SMLoc S = Parser.getTok().getLoc();
1291 StringRef Identifier;
1292 if (Parser.parseIdentifier(Identifier))
1293 return true;
1294 SMLoc E =
1295 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1296 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1297 // Create a symbol reference.
1298 const MCExpr *Res =
1299 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1300
1301 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1302 return false;
1303 }
Jack Carterd76b2372013-03-21 21:44:16 +00001304 // Look for the existing symbol, we should check if
Matheus Almeidad534fc32014-01-30 13:40:26 +00001305 // we need to assign the proper RegisterKind.
Jack Carterd0bd6422013-04-18 00:41:53 +00001306 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1307 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001308 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001309 case AsmToken::LParen:
1310 case AsmToken::Minus:
1311 case AsmToken::Plus:
1312 case AsmToken::Integer:
1313 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001314 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001315 const MCExpr *IdVal;
1316 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001317 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001318 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001319 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001320 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1321 return false;
1322 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001323 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001324 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001325 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001326 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001327 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001328 return true;
1329
Jack Carter873c7242013-01-12 01:03:14 +00001330 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1331
Jack Carterdc1e35d2012-09-06 20:00:02 +00001332 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1333 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001334 } // case AsmToken::Percent
1335 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001336 return true;
1337}
1338
Vladimir Medic4c299852013-11-06 11:27:05 +00001339const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001340 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001341 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001342 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001343 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001344 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001345 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001346 short Val = MCE->getValue();
1347 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001348 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001349 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001350 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001351 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001352 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001353 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001354 if (LoSign)
1355 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001356 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001357 } else {
1358 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001359 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001360 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001361 }
1362
Jack Carterb5cf5902013-04-17 00:18:04 +00001363 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001364 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001365 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001366 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001367 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001368 return Res;
1369 }
1370
1371 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001372 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1373
1374 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1375 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1376 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1377 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1378 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1379 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1380 return MipsMCExpr::CreateHi(Expr, getContext());
1381 return MipsMCExpr::CreateLo(Expr, getContext());
1382 }
1383
Jack Carterd0bd6422013-04-18 00:41:53 +00001384 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1385 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001386 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1387 return Res;
1388 }
1389
1390 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001391 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1392 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1393 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001394 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001395 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001396 return Expr;
1397}
1398
1399bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1400
1401 switch (Expr->getKind()) {
1402 case MCExpr::Constant:
1403 return true;
1404 case MCExpr::SymbolRef:
1405 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1406 case MCExpr::Binary:
1407 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1408 if (!isEvaluated(BE->getLHS()))
1409 return false;
1410 return isEvaluated(BE->getRHS());
1411 }
1412 case MCExpr::Unary:
1413 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001414 case MCExpr::Target:
1415 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001416 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001417 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001418}
Jack Carterd0bd6422013-04-18 00:41:53 +00001419
Jack Carterb5cf5902013-04-17 00:18:04 +00001420bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001421 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001422 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001423 if (Tok.isNot(AsmToken::Identifier))
1424 return true;
1425
1426 std::string Str = Tok.getIdentifier().str();
1427
Jack Carterd0bd6422013-04-18 00:41:53 +00001428 Parser.Lex(); // Eat the identifier.
1429 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001430 const MCExpr *IdVal;
1431 SMLoc EndLoc;
1432
1433 if (getLexer().getKind() == AsmToken::LParen) {
1434 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001435 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001436 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001437 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001438 const AsmToken &nextTok = Parser.getTok();
1439 if (nextTok.isNot(AsmToken::Identifier))
1440 return true;
1441 Str += "(%";
1442 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001443 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001444 if (getLexer().getKind() != AsmToken::LParen)
1445 return true;
1446 } else
1447 break;
1448 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001449 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001450 return true;
1451
1452 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001453 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001454
1455 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001456 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001457
Jack Carterd0bd6422013-04-18 00:41:53 +00001458 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001459 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001460}
1461
Jack Carterb4dbc172012-09-05 23:34:03 +00001462bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1463 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001464 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001465 RegNo = tryParseRegister(isMips64());
1466 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001467 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001468}
1469
Jack Carterb5cf5902013-04-17 00:18:04 +00001470bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001471 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001472 bool Result = true;
1473
1474 while (getLexer().getKind() == AsmToken::LParen)
1475 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001476
Jack Carterd0bd6422013-04-18 00:41:53 +00001477 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001478 default:
1479 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001480 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001481 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001482 case AsmToken::Integer:
1483 case AsmToken::Minus:
1484 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001485 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001486 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001487 else
1488 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001489 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001490 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001491 break;
Jack Carter873c7242013-01-12 01:03:14 +00001492 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001493 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001494 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001495 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001496}
1497
Jack Carterb4dbc172012-09-05 23:34:03 +00001498MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001499 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001500
1501 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001502 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001503 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001504 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001505 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001506 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001507
Jack Carterb5cf5902013-04-17 00:18:04 +00001508 if (getLexer().getKind() == AsmToken::LParen) {
1509 Parser.Lex();
1510 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001511 }
1512
Jack Carterb5cf5902013-04-17 00:18:04 +00001513 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001514 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001515 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001516
Jack Carterd0bd6422013-04-18 00:41:53 +00001517 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001518 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001519 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001520 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001521 SMLoc E =
1522 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001523 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1524 return MatchOperand_Success;
1525 }
1526 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001527 SMLoc E =
1528 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001529
Jack Carterd0bd6422013-04-18 00:41:53 +00001530 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001531 Operands.push_back(MipsOperand::CreateMem(
1532 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001533 return MatchOperand_Success;
1534 }
1535 Error(Parser.getTok().getLoc(), "'(' expected");
1536 return MatchOperand_ParseFail;
1537 }
1538
Jack Carterd0bd6422013-04-18 00:41:53 +00001539 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001540 }
1541
Vladimir Medic4c299852013-11-06 11:27:05 +00001542 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1543 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001544 if (Res != MatchOperand_Success)
1545 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001546
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001547 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001548 Error(Parser.getTok().getLoc(), "')' expected");
1549 return MatchOperand_ParseFail;
1550 }
1551
Jack Carter873c7242013-01-12 01:03:14 +00001552 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1553
Jack Carterd0bd6422013-04-18 00:41:53 +00001554 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001555
1556 if (IdVal == 0)
1557 IdVal = MCConstantExpr::Create(0, getContext());
1558
Jack Carterd0bd6422013-04-18 00:41:53 +00001559 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001560 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001561 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001562 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001563 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001564 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001565 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1566 int64_t Imm;
1567 if (IdVal->EvaluateAsAbsolute(Imm))
1568 IdVal = MCConstantExpr::Create(Imm, getContext());
1569 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1570 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1571 getContext());
1572 }
1573
Jack Carterdc1e35d2012-09-06 20:00:02 +00001574 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1575 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001576 return MatchOperand_Success;
1577}
1578
Vladimir Medic4c299852013-11-06 11:27:05 +00001579bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1580 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001581 // If the first token is not '$' we have an error.
1582 if (Parser.getTok().isNot(AsmToken::Dollar))
1583 return false;
1584
1585 SMLoc S = Parser.getTok().getLoc();
1586 Parser.Lex();
1587 AsmToken::TokenKind TkKind = getLexer().getKind();
1588 int Reg;
1589
1590 if (TkKind == AsmToken::Integer) {
1591 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1592 regKindToRegClass(RegKind));
1593 if (Reg == -1)
1594 return false;
1595 } else if (TkKind == AsmToken::Identifier) {
1596 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1597 return false;
1598 Reg = getReg(regKindToRegClass(RegKind), Reg);
1599 } else {
1600 return false;
1601 }
1602
1603 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1604 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1605 Operands.push_back(Op);
1606 Parser.Lex();
1607 return true;
1608}
1609
1610MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001611MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1612 MipsOperand::RegisterKind RegKind =
1613 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001614
1615 // Parse index register.
1616 if (!parsePtrReg(Operands, RegKind))
1617 return MatchOperand_NoMatch;
1618
1619 // Parse '('.
1620 if (Parser.getTok().isNot(AsmToken::LParen))
1621 return MatchOperand_NoMatch;
1622
1623 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1624 Parser.Lex();
1625
1626 // Parse base register.
1627 if (!parsePtrReg(Operands, RegKind))
1628 return MatchOperand_NoMatch;
1629
1630 // Parse ')'.
1631 if (Parser.getTok().isNot(AsmToken::RParen))
1632 return MatchOperand_NoMatch;
1633
1634 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1635 Parser.Lex();
1636
1637 return MatchOperand_Success;
1638}
1639
Jack Carter873c7242013-01-12 01:03:14 +00001640MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001641MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001642 int RegKind) {
1643 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001644 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001645 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001646 return MatchOperand_Success;
1647 return MatchOperand_NoMatch;
1648 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001649 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001650 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001651 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001652 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001653 if (!hasConsumedDollar) {
1654 Parser.Lex(); // Eat the '$'
1655 hasConsumedDollar = true;
1656 }
1657 if (getLexer().getKind() == AsmToken::Identifier) {
1658 int RegNum = -1;
1659 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001660 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001661 switch (RegKind) {
1662 case MipsOperand::Kind_GPR32:
1663 case MipsOperand::Kind_GPR64:
1664 RegNum = matchCPURegisterName(RegName);
1665 break;
1666 case MipsOperand::Kind_AFGR64Regs:
1667 case MipsOperand::Kind_FGR64Regs:
1668 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001669 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001670 RegNum = matchFPURegisterName(RegName);
1671 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1672 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001673 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1674 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001675 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001676 break;
1677 case MipsOperand::Kind_FCCRegs:
1678 RegNum = matchFCCRegisterName(RegName);
1679 break;
1680 case MipsOperand::Kind_ACC64DSP:
1681 RegNum = matchACRegisterName(RegName);
1682 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001683 default:
1684 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001685 }
1686 // No match found, return _NoMatch to give a chance to other round.
1687 if (RegNum < 0)
1688 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001689
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001690 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1691 if (RegVal == -1)
1692 return MatchOperand_NoMatch;
1693
Vladimir Medic4c299852013-11-06 11:27:05 +00001694 MipsOperand *Op =
1695 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001696 Op->setRegKind(Kind);
1697 Operands.push_back(Op);
1698 hasConsumedDollar = false;
1699 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001700 return MatchOperand_Success;
1701 } else if (getLexer().getKind() == AsmToken::Integer) {
1702 unsigned RegNum = Parser.getTok().getIntVal();
1703 if (Kind == MipsOperand::Kind_HWRegs) {
1704 if (RegNum != 29)
1705 return MatchOperand_NoMatch;
1706 // Only hwreg 29 is supported, found at index 0.
1707 RegNum = 0;
1708 }
1709 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1710 if (Reg == -1)
1711 return MatchOperand_NoMatch;
1712 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1713 Op->setRegKind(Kind);
1714 Operands.push_back(Op);
1715 hasConsumedDollar = false;
1716 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001717 if ((RegKind == MipsOperand::Kind_GPR32) &&
1718 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001719 // Check if it is indexed addressing operand.
1720 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1721 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001722 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001723 return MatchOperand_NoMatch;
1724 if (getLexer().isNot(AsmToken::RParen))
1725 return MatchOperand_NoMatch;
1726 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1727 Parser.Lex();
1728 }
Jack Carter873c7242013-01-12 01:03:14 +00001729 return MatchOperand_Success;
1730 }
1731 return MatchOperand_NoMatch;
1732}
Vladimir Medic64828a12013-07-16 10:07:14 +00001733
Matheus Almeidab74293d2013-10-14 11:49:30 +00001734bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1735 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1736
1737 if (Val < 0)
1738 return false;
1739
1740 switch (Kind) {
1741 default:
1742 return false;
1743 case MipsOperand::Kind_MSA128BRegs:
1744 return Val < 16;
1745 case MipsOperand::Kind_MSA128HRegs:
1746 return Val < 8;
1747 case MipsOperand::Kind_MSA128WRegs:
1748 return Val < 4;
1749 case MipsOperand::Kind_MSA128DRegs:
1750 return Val < 2;
1751 }
1752}
1753
Vladimir Medic8cd17102013-06-20 11:21:49 +00001754MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001755MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001756 int RegKind) {
1757 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1758 SMLoc S = Parser.getTok().getLoc();
1759 std::string RegName;
1760
1761 if (Parser.getTok().isNot(AsmToken::Dollar))
1762 return MatchOperand_NoMatch;
1763
1764 switch (RegKind) {
1765 default:
1766 return MatchOperand_ParseFail;
1767 case MipsOperand::Kind_MSA128BRegs:
1768 case MipsOperand::Kind_MSA128HRegs:
1769 case MipsOperand::Kind_MSA128WRegs:
1770 case MipsOperand::Kind_MSA128DRegs:
1771 break;
1772 }
1773
1774 Parser.Lex(); // Eat the '$'.
1775 if (getLexer().getKind() == AsmToken::Identifier)
1776 RegName = Parser.getTok().getString().lower();
1777 else
1778 return MatchOperand_ParseFail;
1779
1780 int RegNum = matchMSA128RegisterName(RegName);
1781
1782 if (RegNum < 0 || RegNum > 31)
1783 return MatchOperand_ParseFail;
1784
1785 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1786 if (RegVal == -1)
1787 return MatchOperand_ParseFail;
1788
Vladimir Medic4c299852013-11-06 11:27:05 +00001789 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001790 Op->setRegKind(Kind);
1791 Operands.push_back(Op);
1792
1793 Parser.Lex(); // Eat the register identifier.
1794
Matheus Almeidab74293d2013-10-14 11:49:30 +00001795 // MSA registers may be suffixed with an index in the form of:
1796 // 1) Immediate expression.
1797 // 2) General Purpose Register.
1798 // Examples:
1799 // 1) copy_s.b $29,$w0[0]
1800 // 2) sld.b $w0,$w1[$1]
1801
1802 if (Parser.getTok().isNot(AsmToken::LBrac))
1803 return MatchOperand_Success;
1804
1805 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1806
1807 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1808 Parser.Lex(); // Parse the '[' token.
1809
1810 if (Parser.getTok().is(AsmToken::Dollar)) {
1811 // This must be a GPR.
1812 MipsOperand *RegOp;
1813 SMLoc VIdx = Parser.getTok().getLoc();
1814 Parser.Lex(); // Parse the '$' token.
1815
1816 // GPR have aliases and we must account for that. Example: $30 == $fp
1817 if (getLexer().getKind() == AsmToken::Integer) {
1818 unsigned RegNum = Parser.getTok().getIntVal();
1819 int Reg = matchRegisterByNumber(
1820 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1821 if (Reg == -1) {
1822 Error(VIdx, "invalid general purpose register");
1823 return MatchOperand_ParseFail;
1824 }
1825
1826 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1827 } else if (getLexer().getKind() == AsmToken::Identifier) {
1828 int RegNum = -1;
1829 std::string RegName = Parser.getTok().getString().lower();
1830
1831 RegNum = matchCPURegisterName(RegName);
1832 if (RegNum == -1) {
1833 Error(VIdx, "general purpose register expected");
1834 return MatchOperand_ParseFail;
1835 }
1836 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1837 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1838 } else
1839 return MatchOperand_ParseFail;
1840
1841 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1842 Operands.push_back(RegOp);
1843 Parser.Lex(); // Eat the register identifier.
1844
1845 if (Parser.getTok().isNot(AsmToken::RBrac))
1846 return MatchOperand_ParseFail;
1847
1848 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1849 Parser.Lex(); // Parse the ']' token.
1850
1851 return MatchOperand_Success;
1852 }
1853
1854 // The index must be a constant expression then.
1855 SMLoc VIdx = Parser.getTok().getLoc();
1856 const MCExpr *ImmVal;
1857
1858 if (getParser().parseExpression(ImmVal))
1859 return MatchOperand_ParseFail;
1860
1861 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1862 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1863 Error(VIdx, "invalid immediate value");
1864 return MatchOperand_ParseFail;
1865 }
1866
1867 SMLoc E = Parser.getTok().getEndLoc();
1868
1869 if (Parser.getTok().isNot(AsmToken::RBrac))
1870 return MatchOperand_ParseFail;
1871
Vladimir Medic4c299852013-11-06 11:27:05 +00001872 bool insve =
1873 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1874 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001875
1876 // The second vector index of insve instructions is always 0.
1877 if (insve && Operands.size() > 6) {
1878 if (expr->getValue() != 0) {
1879 Error(VIdx, "immediate value must be 0");
1880 return MatchOperand_ParseFail;
1881 }
1882 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1883 } else
1884 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1885
1886 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1887
1888 Parser.Lex(); // Parse the ']' token.
1889
Jack Carter5dc8ac92013-09-25 23:50:44 +00001890 return MatchOperand_Success;
1891}
1892
1893MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001894MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1895 int RegKind) {
1896 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1897
1898 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1899 return MatchOperand_NoMatch;
1900
1901 if (Parser.getTok().isNot(AsmToken::Dollar))
1902 return MatchOperand_ParseFail;
1903
1904 SMLoc S = Parser.getTok().getLoc();
1905
1906 Parser.Lex(); // Eat the '$' symbol.
1907
1908 int RegNum = -1;
1909 if (getLexer().getKind() == AsmToken::Identifier)
1910 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1911 else if (getLexer().getKind() == AsmToken::Integer)
1912 RegNum = Parser.getTok().getIntVal();
1913 else
1914 return MatchOperand_ParseFail;
1915
1916 if (RegNum < 0 || RegNum > 7)
1917 return MatchOperand_ParseFail;
1918
1919 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1920 if (RegVal == -1)
1921 return MatchOperand_ParseFail;
1922
Vladimir Medic4c299852013-11-06 11:27:05 +00001923 MipsOperand *RegOp =
1924 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001925 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1926 Operands.push_back(RegOp);
1927 Parser.Lex(); // Eat the register identifier.
1928
1929 return MatchOperand_Success;
1930}
1931
1932MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001933MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001934
1935 if (!isMips64())
1936 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001937 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001938}
1939
1940MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001941MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1942 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001943}
Jack Carter873c7242013-01-12 01:03:14 +00001944
Vladimir Medic4c299852013-11-06 11:27:05 +00001945MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1946 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001947
1948 if (isFP64())
1949 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001950 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001951}
1952
1953MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001954MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001955 if (!isFP64())
1956 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001957 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001958}
1959
1960MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001961MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1962 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1963}
1964
1965MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1966 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1967 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001968}
1969
Vladimir Medic643b3982013-07-30 10:12:14 +00001970MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001971MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1972 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001973}
1974
1975MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001976MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1977 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001978}
1979
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001980MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001981MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001982 // If the first token is not '$' we have an error.
1983 if (Parser.getTok().isNot(AsmToken::Dollar))
1984 return MatchOperand_NoMatch;
1985
1986 SMLoc S = Parser.getTok().getLoc();
1987 Parser.Lex(); // Eat the '$'
1988
1989 const AsmToken &Tok = Parser.getTok(); // Get next token.
1990
1991 if (Tok.isNot(AsmToken::Identifier))
1992 return MatchOperand_NoMatch;
1993
1994 if (!Tok.getIdentifier().startswith("ac"))
1995 return MatchOperand_NoMatch;
1996
1997 StringRef NumString = Tok.getIdentifier().substr(2);
1998
1999 unsigned IntVal;
2000 if (NumString.getAsInteger(10, IntVal))
2001 return MatchOperand_NoMatch;
2002
2003 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
2004
2005 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2006 Op->setRegKind(MipsOperand::Kind_LO32DSP);
2007 Operands.push_back(Op);
2008
2009 Parser.Lex(); // Eat the register number.
2010 return MatchOperand_Success;
2011}
2012
2013MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002014MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00002015 // If the first token is not '$' we have an error.
2016 if (Parser.getTok().isNot(AsmToken::Dollar))
2017 return MatchOperand_NoMatch;
2018
2019 SMLoc S = Parser.getTok().getLoc();
2020 Parser.Lex(); // Eat the '$'
2021
2022 const AsmToken &Tok = Parser.getTok(); // Get next token.
2023
2024 if (Tok.isNot(AsmToken::Identifier))
2025 return MatchOperand_NoMatch;
2026
2027 if (!Tok.getIdentifier().startswith("ac"))
2028 return MatchOperand_NoMatch;
2029
2030 StringRef NumString = Tok.getIdentifier().substr(2);
2031
2032 unsigned IntVal;
2033 if (NumString.getAsInteger(10, IntVal))
2034 return MatchOperand_NoMatch;
2035
2036 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
2037
2038 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2039 Op->setRegKind(MipsOperand::Kind_HI32DSP);
2040 Operands.push_back(Op);
2041
2042 Parser.Lex(); // Eat the register number.
2043 return MatchOperand_Success;
2044}
2045
Vladimir Medic05bcde62013-09-16 10:29:42 +00002046MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002047MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00002048 // If the first token is not '$' we have an error.
2049 if (Parser.getTok().isNot(AsmToken::Dollar))
2050 return MatchOperand_NoMatch;
2051
2052 SMLoc S = Parser.getTok().getLoc();
2053 Parser.Lex(); // Eat the '$'
2054
2055 const AsmToken &Tok = Parser.getTok(); // Get next token.
2056
2057 if (Tok.isNot(AsmToken::Integer))
2058 return MatchOperand_NoMatch;
2059
2060 unsigned IntVal = Tok.getIntVal();
2061
2062 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2063
2064 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2065 Op->setRegKind(MipsOperand::Kind_COP2);
2066 Operands.push_back(Op);
2067
2068 Parser.Lex(); // Eat the register number.
2069 return MatchOperand_Success;
2070}
2071
Vladimir Medic4c299852013-11-06 11:27:05 +00002072MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2073 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2074 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002075}
2076
Vladimir Medic4c299852013-11-06 11:27:05 +00002077MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2078 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2079 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002080}
2081
Vladimir Medic4c299852013-11-06 11:27:05 +00002082MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2083 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2084 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002085}
2086
Vladimir Medic4c299852013-11-06 11:27:05 +00002087MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2088 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2089 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002090}
2091
Vladimir Medic4c299852013-11-06 11:27:05 +00002092MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2093 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2094 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002095}
2096
Jack Carterd0bd6422013-04-18 00:41:53 +00002097bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002098 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002099
2100 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2101 if (Sym) {
2102 SMLoc S = Parser.getTok().getLoc();
2103 const MCExpr *Expr;
2104 if (Sym->isVariable())
2105 Expr = Sym->getVariableValue();
2106 else
2107 return false;
2108 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002109 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2110 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002111 const StringRef DefSymbol = Ref->getSymbol().getName();
2112 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002113 int RegNum = -1;
2114 APInt IntVal(32, -1);
2115 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2116 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002117 isMips64() ? Mips::GPR64RegClassID
2118 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002119 else {
2120 // Lookup for the register with the corresponding name.
2121 switch (Kind) {
2122 case MipsOperand::Kind_AFGR64Regs:
2123 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002124 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002125 break;
2126 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002127 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002128 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002129 case MipsOperand::Kind_GPR64:
2130 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002131 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002132 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002133 break;
2134 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002135 if (RegNum > -1)
2136 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002137 }
Jack Carterd76b2372013-03-21 21:44:16 +00002138 if (RegNum > -1) {
2139 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002140 MipsOperand *op =
2141 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002142 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002143 Operands.push_back(op);
2144 return true;
2145 }
2146 }
2147 } else if (Expr->getKind() == MCExpr::Constant) {
2148 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002149 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2150 MipsOperand *op =
2151 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002152 Operands.push_back(op);
2153 return true;
2154 }
2155 }
2156 return false;
2157}
Jack Carterd0bd6422013-04-18 00:41:53 +00002158
Jack Carter873c7242013-01-12 01:03:14 +00002159MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002160MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2161 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002162}
2163
2164MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002165MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2166 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002167}
2168
Vladimir Medic2b953d02013-10-01 09:48:56 +00002169MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002170MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002171 const MCExpr *IdVal;
2172 // If the first token is '$' we may have register operand.
2173 if (Parser.getTok().is(AsmToken::Dollar))
2174 return MatchOperand_NoMatch;
2175 SMLoc S = Parser.getTok().getLoc();
2176 if (getParser().parseExpression(IdVal))
2177 return MatchOperand_ParseFail;
2178 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002179 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002180 int64_t Val = MCE->getValue();
2181 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2182 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002183 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002184 return MatchOperand_Success;
2185}
2186
Matheus Almeida779c5932013-11-18 12:32:49 +00002187MipsAsmParser::OperandMatchResultTy
2188MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2189 switch (getLexer().getKind()) {
2190 default:
2191 return MatchOperand_NoMatch;
2192 case AsmToken::LParen:
2193 case AsmToken::Plus:
2194 case AsmToken::Minus:
2195 case AsmToken::Integer:
2196 break;
2197 }
2198
2199 const MCExpr *Expr;
2200 SMLoc S = Parser.getTok().getLoc();
2201
2202 if (getParser().parseExpression(Expr))
2203 return MatchOperand_ParseFail;
2204
2205 int64_t Val;
2206 if (!Expr->EvaluateAsAbsolute(Val)) {
2207 Error(S, "expected immediate value");
2208 return MatchOperand_ParseFail;
2209 }
2210
2211 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2212 // and because the CPU always adds one to the immediate field, the allowed
2213 // range becomes 1..4. We'll only check the range here and will deal
2214 // with the addition/subtraction when actually decoding/encoding
2215 // the instruction.
2216 if (Val < 1 || Val > 4) {
2217 Error(S, "immediate not in range (1..4)");
2218 return MatchOperand_ParseFail;
2219 }
2220
Jack Carter3b2c96e2014-01-22 23:31:38 +00002221 Operands.push_back(
2222 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002223 return MatchOperand_Success;
2224}
2225
Jack Carterdc1e35d2012-09-06 20:00:02 +00002226MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2227
Vladimir Medic4c299852013-11-06 11:27:05 +00002228 MCSymbolRefExpr::VariantKind VK =
2229 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2230 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2231 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2232 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2233 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2234 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2235 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2236 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2237 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2238 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2239 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2240 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2241 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2242 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2243 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2244 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2245 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2246 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2247 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002248
2249 return VK;
2250}
Jack Cartera63b16a2012-09-07 00:23:42 +00002251
Vladimir Medic4c299852013-11-06 11:27:05 +00002252bool MipsAsmParser::ParseInstruction(
2253 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2254 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002255 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002256 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002257 Parser.eatToEndOfStatement();
2258 return Error(NameLoc, "Unknown instruction");
2259 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002260 // First operand in MCInst is instruction mnemonic.
2261 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002262
2263 // Read the remaining operands.
2264 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2265 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002266 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002267 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002268 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002269 return Error(Loc, "unexpected token in argument list");
2270 }
2271
Jack Carterd0bd6422013-04-18 00:41:53 +00002272 while (getLexer().is(AsmToken::Comma)) {
2273 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002274 // Parse and remember the operand.
2275 if (ParseOperand(Operands, Name)) {
2276 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002277 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002278 return Error(Loc, "unexpected token in argument list");
2279 }
2280 }
2281 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002282 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2283 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002284 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002285 return Error(Loc, "unexpected token in argument list");
2286 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002287 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002288 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002289}
2290
Jack Carter0b744b32012-10-04 02:29:46 +00002291bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002292 SMLoc Loc = getLexer().getLoc();
2293 Parser.eatToEndOfStatement();
2294 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002295}
2296
2297bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002298 // Line should look like: ".set noat".
2299 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002300 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002301 // eat noat
2302 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002303 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002304 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2305 reportParseError("unexpected token in statement");
2306 return false;
2307 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002308 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002309 return false;
2310}
Jack Carterd0bd6422013-04-18 00:41:53 +00002311
Jack Carter0b744b32012-10-04 02:29:46 +00002312bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002313 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002314 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002315 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002316 getParser().Lex();
2317 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002318 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002319 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002320 return false;
2321 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002322 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002323 if (getLexer().isNot(AsmToken::Dollar)) {
2324 reportParseError("unexpected token in statement");
2325 return false;
2326 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002327 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002328 const AsmToken &Reg = Parser.getTok();
2329 if (Reg.is(AsmToken::Identifier)) {
2330 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2331 } else if (Reg.is(AsmToken::Integer)) {
2332 AtRegNo = Reg.getIntVal();
2333 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002334 reportParseError("unexpected token in statement");
2335 return false;
2336 }
Jack Carter1ac53222013-02-20 23:11:17 +00002337
Jack Carterd0bd6422013-04-18 00:41:53 +00002338 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002339 reportParseError("unexpected token in statement");
2340 return false;
2341 }
2342
2343 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002344 reportParseError("unexpected token in statement");
2345 return false;
2346 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002347 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002348
2349 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2350 reportParseError("unexpected token in statement");
2351 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002352 }
2353 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002354 return false;
2355 } else {
2356 reportParseError("unexpected token in statement");
2357 return false;
2358 }
2359}
2360
2361bool MipsAsmParser::parseSetReorderDirective() {
2362 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002363 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002364 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2365 reportParseError("unexpected token in statement");
2366 return false;
2367 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002368 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002369 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002370 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002371 return false;
2372}
2373
2374bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002375 Parser.Lex();
2376 // If this is not the end of the statement, report an error.
2377 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2378 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002379 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002380 }
2381 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002382 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002383 Parser.Lex(); // Consume the EndOfStatement.
2384 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002385}
2386
2387bool MipsAsmParser::parseSetMacroDirective() {
2388 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002389 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002390 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2391 reportParseError("unexpected token in statement");
2392 return false;
2393 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002394 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002395 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002396 return false;
2397}
2398
2399bool MipsAsmParser::parseSetNoMacroDirective() {
2400 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002401 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002402 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2403 reportParseError("`noreorder' must be set before `nomacro'");
2404 return false;
2405 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002406 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002407 reportParseError("`noreorder' must be set before `nomacro'");
2408 return false;
2409 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002410 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002411 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002412 return false;
2413}
Jack Carterd76b2372013-03-21 21:44:16 +00002414
Jack Carter39536722014-01-22 23:08:42 +00002415bool MipsAsmParser::parseSetMips16Directive() {
2416 Parser.Lex();
2417 // If this is not the end of the statement, report an error.
2418 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2419 reportParseError("unexpected token in statement");
2420 return false;
2421 }
Rafael Espindolae7583752014-01-24 16:13:20 +00002422 getTargetStreamer().emitDirectiveSetMips16();
Jack Carter39536722014-01-22 23:08:42 +00002423 Parser.Lex(); // Consume the EndOfStatement.
2424 return false;
2425}
2426
2427bool MipsAsmParser::parseSetNoMips16Directive() {
2428 Parser.Lex();
2429 // If this is not the end of the statement, report an error.
2430 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2431 reportParseError("unexpected token in statement");
2432 return false;
2433 }
2434 // For now do nothing.
2435 Parser.Lex(); // Consume the EndOfStatement.
2436 return false;
2437}
2438
Jack Carterd76b2372013-03-21 21:44:16 +00002439bool MipsAsmParser::parseSetAssignment() {
2440 StringRef Name;
2441 const MCExpr *Value;
2442
2443 if (Parser.parseIdentifier(Name))
2444 reportParseError("expected identifier after .set");
2445
2446 if (getLexer().isNot(AsmToken::Comma))
2447 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002448 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002449
Jack Carter3b2c96e2014-01-22 23:31:38 +00002450 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002451 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002452
Jack Carterd0bd6422013-04-18 00:41:53 +00002453 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002454 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002455 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002456 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002457 Sym = getContext().GetOrCreateSymbol(Name);
2458 Sym->setVariableValue(Value);
2459
2460 return false;
2461}
Jack Carterd0bd6422013-04-18 00:41:53 +00002462
Jack Carter0b744b32012-10-04 02:29:46 +00002463bool MipsAsmParser::parseDirectiveSet() {
2464
Jack Carterd0bd6422013-04-18 00:41:53 +00002465 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002466 const AsmToken &Tok = Parser.getTok();
2467
2468 if (Tok.getString() == "noat") {
2469 return parseSetNoAtDirective();
2470 } else if (Tok.getString() == "at") {
2471 return parseSetAtDirective();
2472 } else if (Tok.getString() == "reorder") {
2473 return parseSetReorderDirective();
2474 } else if (Tok.getString() == "noreorder") {
2475 return parseSetNoReorderDirective();
2476 } else if (Tok.getString() == "macro") {
2477 return parseSetMacroDirective();
2478 } else if (Tok.getString() == "nomacro") {
2479 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002480 } else if (Tok.getString() == "mips16") {
2481 return parseSetMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002482 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002483 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002484 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002485 getTargetStreamer().emitDirectiveSetNoMicroMips();
2486 Parser.eatToEndOfStatement();
2487 return false;
2488 } else if (Tok.getString() == "micromips") {
2489 getTargetStreamer().emitDirectiveSetMicroMips();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002490 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002491 return false;
Vladimir Medic615b26e2014-03-04 09:54:09 +00002492 } else if (Tok.getString() == "mips32r2") {
2493 Parser.Lex(); // Eat token.
2494 if (getLexer().isNot(AsmToken::EndOfStatement))
2495 return reportParseError("unexpected token in .set directive");
2496 setFeatureBits(Mips::FeatureMips32r2,"mips32r2");
2497 getTargetStreamer().emitDirectiveSetMips32R2();
2498 return false;
Vladimir Medic27c398e2014-03-05 11:05:09 +00002499 } else if (Tok.getString() == "dsp") {
2500 Parser.Lex(); // Eat token.
2501 if (getLexer().isNot(AsmToken::EndOfStatement))
2502 return reportParseError("unexpected token in .set directive");
2503 setFeatureBits(Mips::FeatureDSP, "dsp");
2504 getTargetStreamer().emitDirectiveSetDsp();
2505 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002506 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002507 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002508 parseSetAssignment();
2509 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002510 }
Jack Carter07c818d2013-01-25 01:31:34 +00002511
Jack Carter0b744b32012-10-04 02:29:46 +00002512 return true;
2513}
2514
Jack Carter07c818d2013-01-25 01:31:34 +00002515/// parseDirectiveWord
2516/// ::= .word [ expression (, expression)* ]
2517bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2518 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2519 for (;;) {
2520 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002521 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002522 return true;
2523
2524 getParser().getStreamer().EmitValue(Value, Size);
2525
2526 if (getLexer().is(AsmToken::EndOfStatement))
2527 break;
2528
2529 // FIXME: Improve diagnostic.
2530 if (getLexer().isNot(AsmToken::Comma))
2531 return Error(L, "unexpected token in directive");
2532 Parser.Lex();
2533 }
2534 }
2535
2536 Parser.Lex();
2537 return false;
2538}
2539
Vladimir Medic4c299852013-11-06 11:27:05 +00002540/// parseDirectiveGpWord
2541/// ::= .gpword local_sym
2542bool MipsAsmParser::parseDirectiveGpWord() {
2543 const MCExpr *Value;
2544 // EmitGPRel32Value requires an expression, so we are using base class
2545 // method to evaluate the expression.
2546 if (getParser().parseExpression(Value))
2547 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002548 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002549
Vladimir Medice10c1122013-11-13 13:18:04 +00002550 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002551 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002552 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002553 return false;
2554}
2555
Jack Carter0cd3c192014-01-06 23:27:31 +00002556bool MipsAsmParser::parseDirectiveOption() {
2557 // Get the option token.
2558 AsmToken Tok = Parser.getTok();
2559 // At the moment only identifiers are supported.
2560 if (Tok.isNot(AsmToken::Identifier)) {
2561 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2562 Parser.eatToEndOfStatement();
2563 return false;
2564 }
2565
2566 StringRef Option = Tok.getIdentifier();
2567
2568 if (Option == "pic0") {
2569 getTargetStreamer().emitDirectiveOptionPic0();
2570 Parser.Lex();
2571 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2572 Error(Parser.getTok().getLoc(),
2573 "unexpected token in .option pic0 directive");
2574 Parser.eatToEndOfStatement();
2575 }
2576 return false;
2577 }
2578
2579 // Unknown option.
2580 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2581 Parser.eatToEndOfStatement();
2582 return false;
2583}
2584
Jack Carter0b744b32012-10-04 02:29:46 +00002585bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002586 StringRef IDVal = DirectiveID.getString();
2587
Jack Carterd0bd6422013-04-18 00:41:53 +00002588 if (IDVal == ".ent") {
2589 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002590 Parser.Lex();
2591 return false;
2592 }
2593
Jack Carter07c818d2013-01-25 01:31:34 +00002594 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002595 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002596 Parser.Lex();
2597 return false;
2598 }
2599
Jack Carter07c818d2013-01-25 01:31:34 +00002600 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002601 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002602 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002603 return false;
2604 }
2605
Jack Carter07c818d2013-01-25 01:31:34 +00002606 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002607 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002608 }
2609
Jack Carter07c818d2013-01-25 01:31:34 +00002610 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002611 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002612 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002613 return false;
2614 }
2615
Jack Carter07c818d2013-01-25 01:31:34 +00002616 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002617 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002618 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002619 return false;
2620 }
2621
Jack Carter07c818d2013-01-25 01:31:34 +00002622 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002623 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002624 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002625 return false;
2626 }
2627
Jack Carter07c818d2013-01-25 01:31:34 +00002628 if (IDVal == ".word") {
2629 parseDirectiveWord(4, DirectiveID.getLoc());
2630 return false;
2631 }
2632
Jack Carter0cd3c192014-01-06 23:27:31 +00002633 if (IDVal == ".option")
2634 return parseDirectiveOption();
2635
2636 if (IDVal == ".abicalls") {
2637 getTargetStreamer().emitDirectiveAbiCalls();
2638 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2639 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2640 // Clear line
2641 Parser.eatToEndOfStatement();
2642 }
2643 return false;
2644 }
2645
Rafael Espindola870c4e92012-01-11 03:56:41 +00002646 return true;
2647}
2648
Rafael Espindola870c4e92012-01-11 03:56:41 +00002649extern "C" void LLVMInitializeMipsAsmParser() {
2650 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2651 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2652 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2653 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2654}
Jack Carterb4dbc172012-09-05 23:34:03 +00002655
2656#define GET_REGISTER_MATCHER
2657#define GET_MATCHER_IMPLEMENTATION
2658#include "MipsGenAsmMatcher.inc"