blob: 2b80d3f03de30a3aa04af1f39a96677f012f8da8 [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 {
Daniel Sanderse34a1202014-03-31 18:51:43 +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;
Daniel Sanderse34a1202014-03-31 18:51:43 +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
Daniel Sanderse34a1202014-03-31 18:51:43 +000088 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
89
90 MipsAsmParser::OperandMatchResultTy
91 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
92
93 MipsAsmParser::OperandMatchResultTy
94 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
Daniel Sanderse34a1202014-03-31 18:51:43 +0000100 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
101 int RegKind);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000102
103 MipsAsmParser::OperandMatchResultTy
Daniel Sanderse34a1202014-03-31 18:51:43 +0000104 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000105
Jack Carter873c7242013-01-12 01:03:14 +0000106 MipsAsmParser::OperandMatchResultTy
Daniel Sanderse34a1202014-03-31 18:51:43 +0000107 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000108
109 MipsAsmParser::OperandMatchResultTy
Daniel Sanderse34a1202014-03-31 18:51:43 +0000110 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000111
112 MipsAsmParser::OperandMatchResultTy
Daniel Sanderse34a1202014-03-31 18:51:43 +0000113 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
114
115 MipsAsmParser::OperandMatchResultTy
116 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
117
118 MipsAsmParser::OperandMatchResultTy
119 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
120
121 MipsAsmParser::OperandMatchResultTy
122 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
123
124 MipsAsmParser::OperandMatchResultTy
125 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
126
127 MipsAsmParser::OperandMatchResultTy
128 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
129
130 MipsAsmParser::OperandMatchResultTy
131 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
132
133 MipsAsmParser::OperandMatchResultTy
134 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
135
136 MipsAsmParser::OperandMatchResultTy
137 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
138
139 MipsAsmParser::OperandMatchResultTy
140 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
141
142 MipsAsmParser::OperandMatchResultTy
143 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
144
145 MipsAsmParser::OperandMatchResultTy
146 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
147
148 MipsAsmParser::OperandMatchResultTy
149 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
150
151 MipsAsmParser::OperandMatchResultTy
152 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
153
154 MipsAsmParser::OperandMatchResultTy
155 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
156
157 MipsAsmParser::OperandMatchResultTy
158 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
Daniel Sanderse34a1202014-03-31 18:51:43 +0000164 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeida779c5932013-11-18 12:32:49 +0000165
Daniel Sanderse34a1202014-03-31 18:51:43 +0000166 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
167 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
Daniel Sanderse34a1202014-03-31 18:51:43 +0000172 int tryParseRegister(bool is64BitReg);
173
174 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
175 bool is64BitReg);
176
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);
Matheus Almeidafe1e39d2014-03-26 14:26:27 +0000198 bool parseSetFeature(uint64_t Feature);
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000199 bool parseDirectiveCPSetup();
Jack Carter0b744b32012-10-04 02:29:46 +0000200 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000201 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000202
203 bool parseSetAtDirective();
204 bool parseSetNoAtDirective();
205 bool parseSetMacroDirective();
206 bool parseSetNoMacroDirective();
207 bool parseSetReorderDirective();
208 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000209 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000210
Jack Carterd76b2372013-03-21 21:44:16 +0000211 bool parseSetAssignment();
212
Matheus Almeida3e2a7022014-03-26 15:24:36 +0000213 bool parseDataDirective(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000214 bool parseDirectiveGpWord();
Rafael Espindola2378d4c2014-03-31 14:15:07 +0000215 bool parseDirectiveGpDWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000216
Jack Carterdc1e35d2012-09-06 20:00:02 +0000217 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000218
Daniel Sanders5e94e682014-03-27 16:42:17 +0000219 bool isGP64() const {
220 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
Jack Carterb4dbc172012-09-05 23:34:03 +0000221 }
222
Jack Cartera63b16a2012-09-07 00:23:42 +0000223 bool isFP64() const {
224 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
225 }
226
Daniel Sandersa4b0c742014-03-26 11:39:07 +0000227 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
Vladimir Medic4c299852013-11-06 11:27:05 +0000228 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000229
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000230 bool isMicroMips() const {
231 return STI.getFeatureBits() & Mips::FeatureMicroMips;
232 }
233
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000234 bool parseRegister(unsigned &RegNum);
235
236 bool eatComma(StringRef ErrorStr);
237
Daniel Sanderse34a1202014-03-31 18:51:43 +0000238 int matchRegisterName(StringRef Symbol, bool is64BitReg);
239
Jack Carter1ac53222013-02-20 23:11:17 +0000240 int matchCPURegisterName(StringRef Symbol);
241
Jack Carter873c7242013-01-12 01:03:14 +0000242 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000243
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000244 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000245
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000246 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000247
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000248 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000249
Jack Carter5dc8ac92013-09-25 23:50:44 +0000250 int matchMSA128RegisterName(StringRef Name);
251
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000252 int matchMSA128CtrlRegisterName(StringRef Name);
253
Daniel Sanderse34a1202014-03-31 18:51:43 +0000254 int regKindToRegClass(int RegKind);
255
Jack Carterd0bd6422013-04-18 00:41:53 +0000256 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000257
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000258 unsigned getGPR(int RegNo);
259
Jack Carter1ac53222013-02-20 23:11:17 +0000260 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000261
Daniel Sanderse34a1202014-03-31 18:51:43 +0000262 // Warn if RegNo is the current assembler temporary.
263 void warnIfAssemblerTemporary(int RegNo);
264
Jack Carter9e65aa32013-03-22 00:05:30 +0000265 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000266 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000267
268 // Helper function that checks if the value of a vector index is within the
269 // boundaries of accepted values for each RegisterKind
270 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
271 bool validateMSAIndex(int Val, int RegKind);
272
Vladimir Medic615b26e2014-03-04 09:54:09 +0000273 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
274 if (!(STI.getFeatureBits() & Feature)) {
275 setAvailableFeatures(ComputeAvailableFeatures(
276 STI.ToggleFeature(FeatureString)));
277 }
278 }
279
280 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
281 if (STI.getFeatureBits() & Feature) {
282 setAvailableFeatures(ComputeAvailableFeatures(
283 STI.ToggleFeature(FeatureString)));
284 }
285 }
286
Rafael Espindola870c4e92012-01-11 03:56:41 +0000287public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000288 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
289 const MCInstrInfo &MII)
Daniel Sanderse34a1202014-03-31 18:51:43 +0000290 : MCTargetAsmParser(), STI(sti), Parser(parser),
291 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000292 // Initialize the set of available features.
293 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000294
295 // Assert exactly one ABI was chosen.
296 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
297 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
298 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
299 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000300 }
301
Jack Carterb4dbc172012-09-05 23:34:03 +0000302 MCAsmParser &getParser() const { return Parser; }
303 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000304};
305}
306
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000307namespace {
308
309/// MipsOperand - Instances of this class represent a parsed Mips machine
310/// instruction.
311class MipsOperand : public MCParsedAsmOperand {
Daniel Sanders0c648ba2014-03-31 17:43:46 +0000312
Daniel Sanderse34a1202014-03-31 18:51:43 +0000313public:
314 enum RegisterKind {
315 Kind_None,
316 Kind_GPR32,
317 Kind_GPR64,
318 Kind_HWRegs,
319 Kind_FGR32Regs,
320 Kind_FGRH32Regs,
321 Kind_FGR64Regs,
322 Kind_AFGR64Regs,
323 Kind_CCRRegs,
324 Kind_FCCRegs,
325 Kind_ACC64DSP,
326 Kind_LO32DSP,
327 Kind_HI32DSP,
328 Kind_COP2,
329 Kind_MSA128BRegs,
330 Kind_MSA128HRegs,
331 Kind_MSA128WRegs,
332 Kind_MSA128DRegs,
333 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000334 };
335
336private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000337 enum KindTy {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000338 k_CondCode,
339 k_CoprocNum,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000340 k_Immediate,
341 k_Memory,
Daniel Sanderse34a1202014-03-31 18:51:43 +0000342 k_PostIndexRegister,
343 k_Register,
344 k_PtrReg,
345 k_Token,
346 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000347 } Kind;
348
Daniel Sanderse34a1202014-03-31 18:51:43 +0000349 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000350
Eric Christopher8996c5d2013-03-15 00:42:55 +0000351 struct Token {
352 const char *Data;
353 unsigned Length;
354 };
355
Daniel Sanderse34a1202014-03-31 18:51:43 +0000356 struct RegOp {
357 unsigned RegNum;
358 RegisterKind Kind;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000359 };
360
361 struct ImmOp {
362 const MCExpr *Val;
363 };
364
365 struct MemOp {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000366 unsigned Base;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000367 const MCExpr *Off;
368 };
369
Jack Carterb4dbc172012-09-05 23:34:03 +0000370 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000371 struct Token Tok;
Daniel Sanderse34a1202014-03-31 18:51:43 +0000372 struct RegOp Reg;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000373 struct ImmOp Imm;
374 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000375 };
376
377 SMLoc StartLoc, EndLoc;
378
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000379public:
Daniel Sanderse34a1202014-03-31 18:51:43 +0000380 void addRegOperands(MCInst &Inst, unsigned N) const {
381 assert(N == 1 && "Invalid number of operands!");
382 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000383 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000384
Daniel Sanderse34a1202014-03-31 18:51:43 +0000385 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
386 assert(N == 1 && "Invalid number of operands!");
387 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000388 }
389
Vladimir Medic4c299852013-11-06 11:27:05 +0000390 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000391 // Add as immediate when possible. Null MCExpr = 0.
392 if (Expr == 0)
393 Inst.addOperand(MCOperand::CreateImm(0));
394 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
395 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
396 else
397 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000398 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000399
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000400 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000401 assert(N == 1 && "Invalid number of operands!");
402 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000403 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000404 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000405
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000406 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000407 assert(N == 2 && "Invalid number of operands!");
408
Daniel Sanderse34a1202014-03-31 18:51:43 +0000409 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
Jack Carterdc1e35d2012-09-06 20:00:02 +0000410
411 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000412 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000413 }
414
Daniel Sanderse34a1202014-03-31 18:51:43 +0000415 bool isReg() const { return Kind == k_Register; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000416 bool isImm() const { return Kind == k_Immediate; }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000417 bool isToken() const { return Kind == k_Token; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000418 bool isMem() const { return Kind == k_Memory; }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000419 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000420 bool isInvNum() const { return Kind == k_Immediate; }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000421 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000422
423 StringRef getToken() const {
424 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000425 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000426 }
427
428 unsigned getReg() const {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000429 assert((Kind == k_Register) && "Invalid access!");
430 return Reg.RegNum;
431 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000432
Daniel Sanderse34a1202014-03-31 18:51:43 +0000433 unsigned getPtrReg() const {
434 assert((Kind == k_PtrReg) && "Invalid access!");
435 return Reg.RegNum;
436 }
437
438 void setRegKind(RegisterKind RegKind) {
439 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
440 Reg.Kind = RegKind;
Jack Carter873c7242013-01-12 01:03:14 +0000441 }
442
Jack Carterb4dbc172012-09-05 23:34:03 +0000443 const MCExpr *getImm() const {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000444 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000445 return Imm.Val;
446 }
447
Daniel Sanderse34a1202014-03-31 18:51:43 +0000448 unsigned getMemBase() const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000449 assert((Kind == k_Memory) && "Invalid access!");
450 return Mem.Base;
451 }
452
453 const MCExpr *getMemOff() const {
454 assert((Kind == k_Memory) && "Invalid access!");
455 return Mem.Off;
456 }
457
Daniel Sanderse34a1202014-03-31 18:51:43 +0000458 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
459 MipsOperand *Op = new MipsOperand(k_Token);
Jack Carterb4dbc172012-09-05 23:34:03 +0000460 Op->Tok.Data = Str.data();
461 Op->Tok.Length = Str.size();
462 Op->StartLoc = S;
463 Op->EndLoc = S;
464 return Op;
465 }
466
Daniel Sanderse34a1202014-03-31 18:51:43 +0000467 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
468 MipsOperand *Op = new MipsOperand(k_Register);
469 Op->Reg.RegNum = RegNum;
470 Op->Reg.Kind = Kind_None;
471 Op->StartLoc = S;
472 Op->EndLoc = E;
473 return Op;
Jack Carterb4dbc172012-09-05 23:34:03 +0000474 }
475
Daniel Sanderse34a1202014-03-31 18:51:43 +0000476 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
477 MipsOperand *Op = new MipsOperand(k_PtrReg);
478 Op->Reg.RegNum = RegNum;
479 Op->Reg.Kind = Kind_None;
480 Op->StartLoc = S;
481 Op->EndLoc = E;
482 return Op;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000483 }
484
Daniel Sanderse34a1202014-03-31 18:51:43 +0000485 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
486 MipsOperand *Op = new MipsOperand(k_Immediate);
Jack Carterb4dbc172012-09-05 23:34:03 +0000487 Op->Imm.Val = Val;
488 Op->StartLoc = S;
489 Op->EndLoc = E;
490 return Op;
491 }
492
Daniel Sanderse34a1202014-03-31 18:51:43 +0000493 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
494 MipsOperand *Op = new MipsOperand(k_LSAImm);
495 Op->Imm.Val = Val;
496 Op->StartLoc = S;
497 Op->EndLoc = E;
498 return Op;
499 }
500
501 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
502 SMLoc E) {
503 MipsOperand *Op = new MipsOperand(k_Memory);
Jack Carterdc1e35d2012-09-06 20:00:02 +0000504 Op->Mem.Base = Base;
505 Op->Mem.Off = Off;
506 Op->StartLoc = S;
507 Op->EndLoc = E;
508 return Op;
509 }
510
Daniel Sanderse34a1202014-03-31 18:51:43 +0000511 bool isGPR32Asm() const {
512 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000513 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000514 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
515 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
Jack Carter873c7242013-01-12 01:03:14 +0000516 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000517
518 bool isGPR64Asm() const {
519 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000520 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000521
522 bool isHWRegsAsm() const {
523 assert((Kind == k_Register) && "Invalid access!");
524 return Reg.Kind == Kind_HWRegs;
Jack Carter873c7242013-01-12 01:03:14 +0000525 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000526
527 bool isCCRAsm() const {
528 assert((Kind == k_Register) && "Invalid access!");
529 return Reg.Kind == Kind_CCRRegs;
Jack Carter873c7242013-01-12 01:03:14 +0000530 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000531
532 bool isAFGR64Asm() const {
533 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
Vladimir Medic233dd512013-06-24 10:05:34 +0000534 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000535
536 bool isFGR64Asm() const {
537 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
Vladimir Medic233dd512013-06-24 10:05:34 +0000538 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000539
540 bool isFGR32Asm() const {
541 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
Vladimir Medic233dd512013-06-24 10:05:34 +0000542 }
Daniel Sanderse34a1202014-03-31 18:51:43 +0000543
544 bool isFGRH32Asm() const {
545 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
546 }
547
548 bool isFCCRegsAsm() const {
549 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
550 }
551
552 bool isACC64DSPAsm() const {
553 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
554 }
555
556 bool isLO32DSPAsm() const {
557 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
558 }
559
560 bool isHI32DSPAsm() const {
561 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
562 }
563
564 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
565
566 bool isMSA128BAsm() const {
567 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
568 }
569
570 bool isMSA128HAsm() const {
571 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
572 }
573
574 bool isMSA128WAsm() const {
575 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
576 }
577
578 bool isMSA128DAsm() const {
579 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
580 }
581
582 bool isMSA128CRAsm() const {
583 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000584 }
585
Jack Carterb4dbc172012-09-05 23:34:03 +0000586 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000587 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000588 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000589 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000590
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000591 virtual void print(raw_ostream &OS) const {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000592 llvm_unreachable("unimplemented!");
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000593 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000594}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000595} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000596
Jack Carter9e65aa32013-03-22 00:05:30 +0000597namespace llvm {
598extern const MCInstrDesc MipsInsts[];
599}
600static const MCInstrDesc &getInstDesc(unsigned Opcode) {
601 return MipsInsts[Opcode];
602}
603
604bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000605 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000606 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000607
Jack Carter9e65aa32013-03-22 00:05:30 +0000608 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000609
610 if (MCID.isBranch() || MCID.isCall()) {
611 const unsigned Opcode = Inst.getOpcode();
612 MCOperand Offset;
613
614 switch (Opcode) {
615 default:
616 break;
617 case Mips::BEQ:
618 case Mips::BNE:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000619 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000620 Offset = Inst.getOperand(2);
621 if (!Offset.isImm())
622 break; // We'll deal with this situation later on when applying fixups.
623 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
624 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000625 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000626 return Error(IDLoc, "branch to misaligned address");
627 break;
628 case Mips::BGEZ:
629 case Mips::BGTZ:
630 case Mips::BLEZ:
631 case Mips::BLTZ:
632 case Mips::BGEZAL:
633 case Mips::BLTZAL:
634 case Mips::BC1F:
635 case Mips::BC1T:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000636 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000637 Offset = Inst.getOperand(1);
638 if (!Offset.isImm())
639 break; // We'll deal with this situation later on when applying fixups.
640 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
641 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000642 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000643 return Error(IDLoc, "branch to misaligned address");
644 break;
645 }
646 }
647
Jack Carterc15c1d22013-04-25 23:31:35 +0000648 if (MCID.hasDelaySlot() && Options.isReorder()) {
649 // If this instruction has a delay slot and .set reorder is active,
650 // emit a NOP after it.
651 Instructions.push_back(Inst);
652 MCInst NopInst;
653 NopInst.setOpcode(Mips::SLL);
654 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
655 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
656 NopInst.addOperand(MCOperand::CreateImm(0));
657 Instructions.push_back(NopInst);
658 return false;
659 }
660
Jack Carter9e65aa32013-03-22 00:05:30 +0000661 if (MCID.mayLoad() || MCID.mayStore()) {
662 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000663 // reference or immediate we may have to expand instructions.
664 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000665 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000666 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
667 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000668 MCOperand &Op = Inst.getOperand(i);
669 if (Op.isImm()) {
670 int MemOffset = Op.getImm();
671 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000672 // Offset can't exceed 16bit value.
673 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000674 return false;
675 }
676 } else if (Op.isExpr()) {
677 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000678 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000679 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000680 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000681 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000682 // Expand symbol.
683 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000684 return false;
685 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000686 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000687 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000688 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000689 }
690 }
691 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000692 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000693 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000694
695 if (needsExpansion(Inst))
696 expandInstruction(Inst, IDLoc, Instructions);
697 else
698 Instructions.push_back(Inst);
699
700 return false;
701}
702
Jack Carter30a59822012-10-04 04:03:53 +0000703bool MipsAsmParser::needsExpansion(MCInst &Inst) {
704
Jack Carterd0bd6422013-04-18 00:41:53 +0000705 switch (Inst.getOpcode()) {
706 case Mips::LoadImm32Reg:
707 case Mips::LoadAddr32Imm:
708 case Mips::LoadAddr32Reg:
Daniel Sandersa771fef2014-03-24 14:05:39 +0000709 case Mips::SUBi:
710 case Mips::SUBiu:
711 case Mips::DSUBi:
712 case Mips::DSUBiu:
Jack Carterd0bd6422013-04-18 00:41:53 +0000713 return true;
714 default:
715 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000716 }
717}
Jack Carter92995f12012-10-06 00:53:28 +0000718
Jack Carter30a59822012-10-04 04:03:53 +0000719void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000720 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000721 switch (Inst.getOpcode()) {
722 case Mips::LoadImm32Reg:
723 return expandLoadImm(Inst, IDLoc, Instructions);
724 case Mips::LoadAddr32Imm:
725 return expandLoadAddressImm(Inst, IDLoc, Instructions);
726 case Mips::LoadAddr32Reg:
727 return expandLoadAddressReg(Inst, IDLoc, Instructions);
Daniel Sandersa771fef2014-03-24 14:05:39 +0000728 case Mips::SUBi:
729 Instructions.push_back(MCInstBuilder(Mips::ADDi)
730 .addReg(Inst.getOperand(0).getReg())
731 .addReg(Inst.getOperand(1).getReg())
732 .addImm(-Inst.getOperand(2).getImm()));
733 return;
734 case Mips::SUBiu:
735 Instructions.push_back(MCInstBuilder(Mips::ADDiu)
736 .addReg(Inst.getOperand(0).getReg())
737 .addReg(Inst.getOperand(1).getReg())
738 .addImm(-Inst.getOperand(2).getImm()));
739 return;
740 case Mips::DSUBi:
741 Instructions.push_back(MCInstBuilder(Mips::DADDi)
742 .addReg(Inst.getOperand(0).getReg())
743 .addReg(Inst.getOperand(1).getReg())
744 .addImm(-Inst.getOperand(2).getImm()));
745 return;
746 case Mips::DSUBiu:
747 Instructions.push_back(MCInstBuilder(Mips::DADDiu)
748 .addReg(Inst.getOperand(0).getReg())
749 .addReg(Inst.getOperand(1).getReg())
750 .addImm(-Inst.getOperand(2).getImm()));
751 return;
Jack Carterd0bd6422013-04-18 00:41:53 +0000752 }
Jack Carter30a59822012-10-04 04:03:53 +0000753}
Jack Carter92995f12012-10-06 00:53:28 +0000754
Jack Carter30a59822012-10-04 04:03:53 +0000755void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000756 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000757 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000758 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000759 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000760 const MCOperand &RegOp = Inst.getOperand(0);
761 assert(RegOp.isReg() && "expected register operand kind");
762
763 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000764 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000765 if (0 <= ImmValue && ImmValue <= 65535) {
766 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000767 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000768 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000769 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000770 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000771 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000772 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000773 } else if (ImmValue < 0 && ImmValue >= -32768) {
774 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000775 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000776 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000777 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000778 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000779 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000780 Instructions.push_back(tmpInst);
781 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000782 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000783 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000784 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000785 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000786 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
787 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000788 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000789 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000790 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000791 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
792 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
793 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
794 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000795 Instructions.push_back(tmpInst);
796 }
797}
Jack Carter92995f12012-10-06 00:53:28 +0000798
Vladimir Medic4c299852013-11-06 11:27:05 +0000799void
800MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
801 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000802 MCInst tmpInst;
803 const MCOperand &ImmOp = Inst.getOperand(2);
804 assert(ImmOp.isImm() && "expected immediate operand kind");
805 const MCOperand &SrcRegOp = Inst.getOperand(1);
806 assert(SrcRegOp.isReg() && "expected register operand kind");
807 const MCOperand &DstRegOp = Inst.getOperand(0);
808 assert(DstRegOp.isReg() && "expected register operand kind");
809 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000810 if (-32768 <= ImmValue && ImmValue <= 65535) {
811 // For -32768 <= j <= 65535.
812 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000813 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000814 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
815 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
816 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
817 Instructions.push_back(tmpInst);
818 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000819 // For any other value of j that is representable as a 32-bit integer.
820 // la d,j(s) => lui d,hi16(j)
821 // ori d,d,lo16(j)
822 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000823 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000824 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
825 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
826 Instructions.push_back(tmpInst);
827 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000828 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000829 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
830 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
831 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
832 Instructions.push_back(tmpInst);
833 tmpInst.clear();
834 tmpInst.setOpcode(Mips::ADDu);
835 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
836 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
837 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
838 Instructions.push_back(tmpInst);
839 }
840}
841
Vladimir Medic4c299852013-11-06 11:27:05 +0000842void
843MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
844 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000845 MCInst tmpInst;
846 const MCOperand &ImmOp = Inst.getOperand(1);
847 assert(ImmOp.isImm() && "expected immediate operand kind");
848 const MCOperand &RegOp = Inst.getOperand(0);
849 assert(RegOp.isReg() && "expected register operand kind");
850 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000851 if (-32768 <= ImmValue && ImmValue <= 65535) {
852 // For -32768 <= j <= 65535.
853 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000854 tmpInst.setOpcode(Mips::ADDiu);
855 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000856 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000857 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
858 Instructions.push_back(tmpInst);
859 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000860 // For any other value of j that is representable as a 32-bit integer.
861 // la d,j => lui d,hi16(j)
862 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000863 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000864 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
865 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
866 Instructions.push_back(tmpInst);
867 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000868 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000869 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
870 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
871 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
872 Instructions.push_back(tmpInst);
873 }
874}
875
Jack Carter9e65aa32013-03-22 00:05:30 +0000876void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000877 SmallVectorImpl<MCInst> &Instructions,
878 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000879 const MCSymbolRefExpr *SR;
880 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000881 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000882 const MCExpr *ExprOffset;
883 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000884 unsigned AtRegNum = getReg(
Daniel Sanders5e94e682014-03-27 16:42:17 +0000885 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000886 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000887 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
888 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000889 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000890 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
891 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000892 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000893 if (isImmOpnd) {
894 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
895 ImmOffset = Inst.getOperand(2).getImm();
896 LoOffset = ImmOffset & 0x0000ffff;
897 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000898 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000899 if (LoOffset & 0x8000)
900 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000901 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000902 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000903 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000904 TempInst.setLoc(IDLoc);
905 // 1st instruction in expansion is LUi. For load instruction we can use
906 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 // but for stores we must use $at.
908 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000909 TempInst.setOpcode(Mips::LUi);
910 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
911 if (isImmOpnd)
912 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
913 else {
914 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000915 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000916 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
917 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
918 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000919 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000920 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000921 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000922 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000923 }
924 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000925 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000926 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000927 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000928 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000929 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000930 TempInst.setOpcode(Mips::ADDu);
931 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
932 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
933 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
934 Instructions.push_back(TempInst);
935 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +0000936 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000937 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000938 TempInst.setOpcode(Inst.getOpcode());
939 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
940 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
941 if (isImmOpnd)
942 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
943 else {
944 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000945 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
946 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
947 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000948 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000949 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000950 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000951 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000952 }
953 }
954 Instructions.push_back(TempInst);
955 TempInst.clear();
956}
957
Vladimir Medic4c299852013-11-06 11:27:05 +0000958bool MipsAsmParser::MatchAndEmitInstruction(
959 SMLoc IDLoc, unsigned &Opcode,
960 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
961 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000962 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000963 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000964 unsigned MatchResult =
965 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000966
967 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000968 default:
969 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000970 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000971 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000972 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000973 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +0000974 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +0000975 return false;
976 }
977 case Match_MissingFeature:
978 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
979 return true;
980 case Match_InvalidOperand: {
981 SMLoc ErrorLoc = IDLoc;
982 if (ErrorInfo != ~0U) {
983 if (ErrorInfo >= Operands.size())
984 return Error(IDLoc, "too few operands for instruction");
985
Vladimir Medic4c299852013-11-06 11:27:05 +0000986 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000987 if (ErrorLoc == SMLoc())
988 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000989 }
990
991 return Error(ErrorLoc, "invalid operand for instruction");
992 }
993 case Match_MnemonicFail:
994 return Error(IDLoc, "invalid instruction");
995 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000996 return true;
997}
998
Daniel Sanderse34a1202014-03-31 18:51:43 +0000999void MipsAsmParser::warnIfAssemblerTemporary(int RegNo) {
1000 if ((RegNo != 0) && ((int)Options.getATRegNum() == RegNo)) {
1001 if (RegNo == 1)
1002 Warning(getLexer().getLoc(), "Used $at without \".set noat\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001003 else
Daniel Sanderse34a1202014-03-31 18:51:43 +00001004 Warning(getLexer().getLoc(), Twine("Used $") + Twine(RegNo) +
1005 " with \".set at=$" + Twine(RegNo) +
1006 "\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001007 }
1008}
1009
Jack Carter1ac53222013-02-20 23:11:17 +00001010int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001011 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +00001012
Vladimir Medic4c299852013-11-06 11:27:05 +00001013 CC = StringSwitch<unsigned>(Name)
1014 .Case("zero", 0)
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001015 .Case("at", 1)
Vladimir Medic4c299852013-11-06 11:27:05 +00001016 .Case("a0", 4)
1017 .Case("a1", 5)
1018 .Case("a2", 6)
1019 .Case("a3", 7)
1020 .Case("v0", 2)
1021 .Case("v1", 3)
1022 .Case("s0", 16)
1023 .Case("s1", 17)
1024 .Case("s2", 18)
1025 .Case("s3", 19)
1026 .Case("s4", 20)
1027 .Case("s5", 21)
1028 .Case("s6", 22)
1029 .Case("s7", 23)
1030 .Case("k0", 26)
1031 .Case("k1", 27)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001032 .Case("gp", 28)
Vladimir Medic4c299852013-11-06 11:27:05 +00001033 .Case("sp", 29)
1034 .Case("fp", 30)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001035 .Case("s8", 30)
Vladimir Medic4c299852013-11-06 11:27:05 +00001036 .Case("ra", 31)
1037 .Case("t0", 8)
1038 .Case("t1", 9)
1039 .Case("t2", 10)
1040 .Case("t3", 11)
1041 .Case("t4", 12)
1042 .Case("t5", 13)
1043 .Case("t6", 14)
1044 .Case("t7", 15)
1045 .Case("t8", 24)
1046 .Case("t9", 25)
1047 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001048
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001049 if (isN32() || isN64()) {
1050 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1051 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1052 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1053 if (8 <= CC && CC <= 11)
1054 CC += 4;
Jack Carter1ac53222013-02-20 23:11:17 +00001055
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001056 if (CC == -1)
1057 CC = StringSwitch<unsigned>(Name)
1058 .Case("a4", 8)
1059 .Case("a5", 9)
1060 .Case("a6", 10)
1061 .Case("a7", 11)
1062 .Case("kt0", 26)
1063 .Case("kt1", 27)
1064 .Default(-1);
1065 }
Jack Carter1ac53222013-02-20 23:11:17 +00001066
Daniel Sanderse34a1202014-03-31 18:51:43 +00001067 warnIfAssemblerTemporary(CC);
1068
Jack Carter1ac53222013-02-20 23:11:17 +00001069 return CC;
1070}
Jack Carterd0bd6422013-04-18 00:41:53 +00001071
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001072int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001073
Jack Cartera63b16a2012-09-07 00:23:42 +00001074 if (Name[0] == 'f') {
1075 StringRef NumString = Name.substr(1);
1076 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001077 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001078 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001079 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001080 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001081 return IntVal;
1082 }
1083 return -1;
1084}
Jack Cartera63b16a2012-09-07 00:23:42 +00001085
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001086int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1087
1088 if (Name.startswith("fcc")) {
1089 StringRef NumString = Name.substr(3);
1090 unsigned IntVal;
1091 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001092 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001093 if (IntVal > 7) // There are only 8 fcc registers.
1094 return -1;
1095 return IntVal;
1096 }
1097 return -1;
1098}
1099
1100int MipsAsmParser::matchACRegisterName(StringRef Name) {
1101
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001102 if (Name.startswith("ac")) {
1103 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001104 unsigned IntVal;
1105 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001106 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001107 if (IntVal > 3) // There are only 3 acc registers.
1108 return -1;
1109 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001110 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001111 return -1;
1112}
Jack Carterd0bd6422013-04-18 00:41:53 +00001113
Jack Carter5dc8ac92013-09-25 23:50:44 +00001114int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1115 unsigned IntVal;
1116
1117 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1118 return -1;
1119
1120 if (IntVal > 31)
1121 return -1;
1122
1123 return IntVal;
1124}
1125
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001126int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1127 int CC;
1128
1129 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001130 .Case("msair", 0)
1131 .Case("msacsr", 1)
1132 .Case("msaaccess", 2)
1133 .Case("msasave", 3)
1134 .Case("msamodify", 4)
1135 .Case("msarequest", 5)
1136 .Case("msamap", 6)
1137 .Case("msaunmap", 7)
1138 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001139
1140 return CC;
1141}
1142
Daniel Sanderse34a1202014-03-31 18:51:43 +00001143int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1144
1145 int CC;
1146 CC = matchCPURegisterName(Name);
1147 if (CC != -1)
1148 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1149 : Mips::GPR32RegClassID);
1150 CC = matchFPURegisterName(Name);
1151 // TODO: decide about fpu register class
1152 if (CC != -1)
1153 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1154 : Mips::FGR32RegClassID);
1155 return matchMSA128RegisterName(Name);
1156}
1157
1158int MipsAsmParser::regKindToRegClass(int RegKind) {
1159
1160 switch (RegKind) {
1161 case MipsOperand::Kind_GPR32:
1162 return Mips::GPR32RegClassID;
1163 case MipsOperand::Kind_GPR64:
1164 return Mips::GPR64RegClassID;
1165 case MipsOperand::Kind_HWRegs:
1166 return Mips::HWRegsRegClassID;
1167 case MipsOperand::Kind_FGR32Regs:
1168 return Mips::FGR32RegClassID;
1169 case MipsOperand::Kind_FGRH32Regs:
1170 return Mips::FGRH32RegClassID;
1171 case MipsOperand::Kind_FGR64Regs:
1172 return Mips::FGR64RegClassID;
1173 case MipsOperand::Kind_AFGR64Regs:
1174 return Mips::AFGR64RegClassID;
1175 case MipsOperand::Kind_CCRRegs:
1176 return Mips::CCRRegClassID;
1177 case MipsOperand::Kind_ACC64DSP:
1178 return Mips::ACC64DSPRegClassID;
1179 case MipsOperand::Kind_FCCRegs:
1180 return Mips::FCCRegClassID;
1181 case MipsOperand::Kind_MSA128BRegs:
1182 return Mips::MSA128BRegClassID;
1183 case MipsOperand::Kind_MSA128HRegs:
1184 return Mips::MSA128HRegClassID;
1185 case MipsOperand::Kind_MSA128WRegs:
1186 return Mips::MSA128WRegClassID;
1187 case MipsOperand::Kind_MSA128DRegs:
1188 return Mips::MSA128DRegClassID;
1189 case MipsOperand::Kind_MSA128CtrlRegs:
1190 return Mips::MSACtrlRegClassID;
1191 default:
1192 return -1;
1193 }
1194}
1195
Jack Carter0b744b32012-10-04 02:29:46 +00001196bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1197 if (Reg > 31)
1198 return false;
1199
1200 aTReg = Reg;
1201 return true;
1202}
1203
Daniel Sandersd89b1362014-03-24 16:48:01 +00001204int MipsAsmParser::getATReg() {
1205 int AT = Options.getATRegNum();
1206 if (AT == 0)
1207 TokError("Pseudo instruction requires $at, which is not available");
1208 return AT;
1209}
Jack Carter0b744b32012-10-04 02:29:46 +00001210
Jack Carterd0bd6422013-04-18 00:41:53 +00001211unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001212 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001213}
1214
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001215unsigned MipsAsmParser::getGPR(int RegNo) {
Daniel Sanders5e94e682014-03-27 16:42:17 +00001216 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1217 RegNo);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001218}
1219
Jack Carter873c7242013-01-12 01:03:14 +00001220int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001221 if (RegNum >
Daniel Sanders64cf5a42014-03-27 15:00:44 +00001222 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
Jack Carterb4dbc172012-09-05 23:34:03 +00001223 return -1;
1224
Daniel Sanderse34a1202014-03-31 18:51:43 +00001225 if (RegClass == Mips::GPR32RegClassID || RegClass == Mips::GPR64RegClassID)
1226 warnIfAssemblerTemporary(RegNum);
1227
Jack Carter873c7242013-01-12 01:03:14 +00001228 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001229}
1230
Daniel Sanderse34a1202014-03-31 18:51:43 +00001231int MipsAsmParser::tryParseRegister(bool is64BitReg) {
1232 const AsmToken &Tok = Parser.getTok();
1233 int RegNum = -1;
1234
1235 if (Tok.is(AsmToken::Identifier)) {
1236 std::string lowerCase = Tok.getString().lower();
1237 RegNum = matchRegisterName(lowerCase, is64BitReg);
1238 } else if (Tok.is(AsmToken::Integer))
1239 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
1240 is64BitReg ? Mips::GPR64RegClassID
1241 : Mips::GPR32RegClassID);
1242 return RegNum;
1243}
1244
1245bool MipsAsmParser::tryParseRegisterOperand(
1246 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
1247
1248 SMLoc S = Parser.getTok().getLoc();
1249 int RegNo = -1;
1250
1251 RegNo = tryParseRegister(is64BitReg);
1252 if (RegNo == -1)
1253 return true;
1254
1255 Operands.push_back(
1256 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1257 Parser.Lex(); // Eat register token.
1258 return false;
1259}
1260
Vladimir Medic4c299852013-11-06 11:27:05 +00001261bool
1262MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1263 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001264 // Check if the current operand has a custom associated parser, if so, try to
1265 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001266 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1267 if (ResTy == MatchOperand_Success)
1268 return false;
1269 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1270 // there was a match, but an error occurred, in which case, just return that
1271 // the operand parsing failed.
1272 if (ResTy == MatchOperand_ParseFail)
1273 return true;
1274
1275 switch (getLexer().getKind()) {
1276 default:
1277 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1278 return true;
1279 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001280 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001281 SMLoc S = Parser.getTok().getLoc();
Daniel Sanderse34a1202014-03-31 18:51:43 +00001282 Parser.Lex(); // Eat dollar token.
1283 // Parse the register operand.
1284 if (!tryParseRegisterOperand(Operands, isGP64())) {
1285 if (getLexer().is(AsmToken::LParen)) {
1286 // Check if it is indexed addressing operand.
1287 Operands.push_back(MipsOperand::CreateToken("(", S));
1288 Parser.Lex(); // Eat the parenthesis.
1289 if (getLexer().isNot(AsmToken::Dollar))
1290 return true;
Jack Carterb4dbc172012-09-05 23:34:03 +00001291
Daniel Sanderse34a1202014-03-31 18:51:43 +00001292 Parser.Lex(); // Eat the dollar
1293 if (tryParseRegisterOperand(Operands, isGP64()))
1294 return true;
1295
1296 if (!getLexer().is(AsmToken::RParen))
1297 return true;
1298
1299 S = Parser.getTok().getLoc();
1300 Operands.push_back(MipsOperand::CreateToken(")", S));
1301 Parser.Lex();
1302 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001303 return false;
Daniel Sanderse34a1202014-03-31 18:51:43 +00001304 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001305 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001306 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001307 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001308 return true;
1309
Jack Carter873c7242013-01-12 01:03:14 +00001310 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001311 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001312 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001313 const MCExpr *Res =
1314 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001315
Daniel Sanderse34a1202014-03-31 18:51:43 +00001316 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
Jack Carterb4dbc172012-09-05 23:34:03 +00001317 return false;
1318 }
Daniel Sanderse34a1202014-03-31 18:51:43 +00001319 case AsmToken::Identifier:
1320 // For instruction aliases like "bc1f $Label" dedicated parser will
1321 // eat the '$' sign before failing. So in order to look for appropriate
1322 // label we must check first if we have already consumed '$'.
1323 if (hasConsumedDollar) {
1324 hasConsumedDollar = false;
1325 SMLoc S = Parser.getTok().getLoc();
1326 StringRef Identifier;
1327 if (Parser.parseIdentifier(Identifier))
1328 return true;
1329 SMLoc E =
1330 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1331 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1332 // Create a symbol reference.
1333 const MCExpr *Res =
1334 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1335
1336 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1337 return false;
1338 }
1339 // Look for the existing symbol, we should check if
1340 // we need to assign the proper RegisterKind.
1341 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1342 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001343 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001344 case AsmToken::LParen:
1345 case AsmToken::Minus:
1346 case AsmToken::Plus:
1347 case AsmToken::Integer:
1348 case AsmToken::String: {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001349 // Quoted label names.
1350 const MCExpr *IdVal;
1351 SMLoc S = Parser.getTok().getLoc();
1352 if (getParser().parseExpression(IdVal))
1353 return true;
1354 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1355 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1356 return false;
Jack Carterb4dbc172012-09-05 23:34:03 +00001357 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001358 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001359 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001360 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001361 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001362 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001363 return true;
1364
Jack Carter873c7242013-01-12 01:03:14 +00001365 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1366
Daniel Sanderse34a1202014-03-31 18:51:43 +00001367 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
Jack Carterdc1e35d2012-09-06 20:00:02 +00001368 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001369 } // case AsmToken::Percent
1370 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001371 return true;
1372}
1373
Vladimir Medic4c299852013-11-06 11:27:05 +00001374const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001375 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001376 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001377 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001378 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001379 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001380 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001381 short Val = MCE->getValue();
1382 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001383 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001384 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001385 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001386 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001387 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001388 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001389 if (LoSign)
1390 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001391 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001392 } else {
1393 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001394 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001395 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001396 }
1397
Jack Carterb5cf5902013-04-17 00:18:04 +00001398 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001399 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001400 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001401 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001402 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001403 return Res;
1404 }
1405
1406 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001407 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1408
1409 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1410 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1411 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1412 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1413 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1414 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1415 return MipsMCExpr::CreateHi(Expr, getContext());
1416 return MipsMCExpr::CreateLo(Expr, getContext());
1417 }
1418
Jack Carterd0bd6422013-04-18 00:41:53 +00001419 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1420 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001421 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1422 return Res;
1423 }
1424
1425 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001426 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1427 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1428 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001429 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001430 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001431 return Expr;
1432}
1433
1434bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1435
1436 switch (Expr->getKind()) {
1437 case MCExpr::Constant:
1438 return true;
1439 case MCExpr::SymbolRef:
1440 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1441 case MCExpr::Binary:
1442 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1443 if (!isEvaluated(BE->getLHS()))
1444 return false;
1445 return isEvaluated(BE->getRHS());
1446 }
1447 case MCExpr::Unary:
1448 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001449 case MCExpr::Target:
1450 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001451 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001452 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001453}
Jack Carterd0bd6422013-04-18 00:41:53 +00001454
Jack Carterb5cf5902013-04-17 00:18:04 +00001455bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001456 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001457 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001458 if (Tok.isNot(AsmToken::Identifier))
1459 return true;
1460
1461 std::string Str = Tok.getIdentifier().str();
1462
Jack Carterd0bd6422013-04-18 00:41:53 +00001463 Parser.Lex(); // Eat the identifier.
1464 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001465 const MCExpr *IdVal;
1466 SMLoc EndLoc;
1467
1468 if (getLexer().getKind() == AsmToken::LParen) {
1469 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001470 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001471 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001472 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001473 const AsmToken &nextTok = Parser.getTok();
1474 if (nextTok.isNot(AsmToken::Identifier))
1475 return true;
1476 Str += "(%";
1477 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001478 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001479 if (getLexer().getKind() != AsmToken::LParen)
1480 return true;
1481 } else
1482 break;
1483 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001484 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001485 return true;
1486
1487 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001488 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001489
1490 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001491 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001492
Jack Carterd0bd6422013-04-18 00:41:53 +00001493 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001494 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001495}
1496
Jack Carterb4dbc172012-09-05 23:34:03 +00001497bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1498 SMLoc &EndLoc) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001499 StartLoc = Parser.getTok().getLoc();
1500 RegNo = tryParseRegister(isGP64());
1501 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001502 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001503}
1504
Jack Carterb5cf5902013-04-17 00:18:04 +00001505bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001506 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001507 bool Result = true;
1508
1509 while (getLexer().getKind() == AsmToken::LParen)
1510 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001511
Jack Carterd0bd6422013-04-18 00:41:53 +00001512 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001513 default:
1514 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001515 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001516 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001517 case AsmToken::Integer:
1518 case AsmToken::Minus:
1519 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001520 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001521 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001522 else
1523 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001524 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001525 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001526 break;
Jack Carter873c7242013-01-12 01:03:14 +00001527 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001528 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001529 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001530 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001531}
1532
Jack Carterb4dbc172012-09-05 23:34:03 +00001533MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001534 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001535
Jack Carterdc1e35d2012-09-06 20:00:02 +00001536 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001537 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001538 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001539 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001540 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001541 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001542
Jack Carterb5cf5902013-04-17 00:18:04 +00001543 if (getLexer().getKind() == AsmToken::LParen) {
1544 Parser.Lex();
1545 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001546 }
1547
Jack Carterb5cf5902013-04-17 00:18:04 +00001548 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001549 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001550 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001551
Jack Carterd0bd6422013-04-18 00:41:53 +00001552 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001553 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001554 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001555 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001556 SMLoc E =
1557 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Daniel Sanderse34a1202014-03-31 18:51:43 +00001558 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001559 return MatchOperand_Success;
1560 }
1561 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001562 SMLoc E =
1563 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001564
Jack Carterd0bd6422013-04-18 00:41:53 +00001565 // Zero register assumed, add a memory operand with ZERO as its base.
Daniel Sanderse34a1202014-03-31 18:51:43 +00001566 Operands.push_back(MipsOperand::CreateMem(
1567 isGP64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001568 return MatchOperand_Success;
1569 }
1570 Error(Parser.getTok().getLoc(), "'(' expected");
1571 return MatchOperand_ParseFail;
1572 }
1573
Jack Carterd0bd6422013-04-18 00:41:53 +00001574 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001575 }
1576
Daniel Sanderse34a1202014-03-31 18:51:43 +00001577 Res = parseRegs(Operands, isGP64() ? (int)MipsOperand::Kind_GPR64
1578 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001579 if (Res != MatchOperand_Success)
1580 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001581
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001582 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001583 Error(Parser.getTok().getLoc(), "')' expected");
1584 return MatchOperand_ParseFail;
1585 }
1586
Jack Carter873c7242013-01-12 01:03:14 +00001587 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1588
Jack Carterd0bd6422013-04-18 00:41:53 +00001589 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001590
1591 if (IdVal == 0)
1592 IdVal = MCConstantExpr::Create(0, getContext());
1593
Jack Carterd0bd6422013-04-18 00:41:53 +00001594 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001595 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Daniel Sanderse34a1202014-03-31 18:51:43 +00001596 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001597 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001598 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001599 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001600 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1601 int64_t Imm;
1602 if (IdVal->EvaluateAsAbsolute(Imm))
1603 IdVal = MCConstantExpr::Create(Imm, getContext());
1604 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1605 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1606 getContext());
1607 }
1608
Daniel Sanderse34a1202014-03-31 18:51:43 +00001609 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1610 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001611 return MatchOperand_Success;
1612}
1613
Daniel Sanderse34a1202014-03-31 18:51:43 +00001614bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1615 int RegKind) {
1616 // If the first token is not '$' we have an error.
1617 if (Parser.getTok().isNot(AsmToken::Dollar))
1618 return false;
1619
1620 SMLoc S = Parser.getTok().getLoc();
1621 Parser.Lex();
1622 AsmToken::TokenKind TkKind = getLexer().getKind();
1623 int Reg;
1624
1625 if (TkKind == AsmToken::Integer) {
1626 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1627 regKindToRegClass(RegKind));
1628 if (Reg == -1)
1629 return false;
1630 } else if (TkKind == AsmToken::Identifier) {
1631 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1632 return false;
1633 Reg = getReg(regKindToRegClass(RegKind), Reg);
1634 } else {
1635 return false;
1636 }
1637
1638 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1639 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1640 Operands.push_back(Op);
1641 Parser.Lex();
1642 return true;
1643}
1644
1645MipsAsmParser::OperandMatchResultTy
1646MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1647 MipsOperand::RegisterKind RegKind =
1648 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
1649
1650 // Parse index register.
1651 if (!parsePtrReg(Operands, RegKind))
1652 return MatchOperand_NoMatch;
1653
1654 // Parse '('.
1655 if (Parser.getTok().isNot(AsmToken::LParen))
1656 return MatchOperand_NoMatch;
1657
1658 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1659 Parser.Lex();
1660
1661 // Parse base register.
1662 if (!parsePtrReg(Operands, RegKind))
1663 return MatchOperand_NoMatch;
1664
1665 // Parse ')'.
1666 if (Parser.getTok().isNot(AsmToken::RParen))
1667 return MatchOperand_NoMatch;
1668
1669 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1670 Parser.Lex();
1671
1672 return MatchOperand_Success;
1673}
1674
1675MipsAsmParser::OperandMatchResultTy
1676MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1677 int RegKind) {
1678 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1679 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
1680 if (searchSymbolAlias(Operands, Kind))
1681 return MatchOperand_Success;
1682 return MatchOperand_NoMatch;
1683 }
1684 SMLoc S = Parser.getTok().getLoc();
1685 // If the first token is not '$', we have an error.
1686 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1687 return MatchOperand_NoMatch;
1688 if (!hasConsumedDollar) {
1689 Parser.Lex(); // Eat the '$'
1690 hasConsumedDollar = true;
1691 }
1692 if (getLexer().getKind() == AsmToken::Identifier) {
1693 int RegNum = -1;
1694 std::string RegName = Parser.getTok().getString().lower();
1695 // Match register by name
1696 switch (RegKind) {
1697 case MipsOperand::Kind_GPR32:
1698 case MipsOperand::Kind_GPR64:
1699 RegNum = matchCPURegisterName(RegName);
1700 break;
1701 case MipsOperand::Kind_AFGR64Regs:
1702 case MipsOperand::Kind_FGR64Regs:
1703 case MipsOperand::Kind_FGR32Regs:
1704 case MipsOperand::Kind_FGRH32Regs:
1705 RegNum = matchFPURegisterName(RegName);
1706 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1707 RegNum /= 2;
1708 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1709 if (RegNum != -1 && RegNum % 2 != 0)
1710 Warning(S, "Float register should be even.");
1711 break;
1712 case MipsOperand::Kind_FCCRegs:
1713 RegNum = matchFCCRegisterName(RegName);
1714 break;
1715 case MipsOperand::Kind_ACC64DSP:
1716 RegNum = matchACRegisterName(RegName);
1717 break;
1718 default:
1719 break; // No match, value is set to -1.
1720 }
1721 // No match found, return _NoMatch to give a chance to other round.
1722 if (RegNum < 0)
1723 return MatchOperand_NoMatch;
1724
1725 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1726 if (RegVal == -1)
1727 return MatchOperand_NoMatch;
1728
1729 MipsOperand *Op =
1730 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1731 Op->setRegKind(Kind);
1732 Operands.push_back(Op);
1733 hasConsumedDollar = false;
1734 Parser.Lex(); // Eat the register name.
1735 return MatchOperand_Success;
1736 } else if (getLexer().getKind() == AsmToken::Integer) {
1737 unsigned RegNum = Parser.getTok().getIntVal();
1738 if (Kind == MipsOperand::Kind_HWRegs) {
1739 if (RegNum != 29)
1740 return MatchOperand_NoMatch;
1741 // Only hwreg 29 is supported, found at index 0.
1742 RegNum = 0;
1743 }
1744 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1745 if (Reg == -1)
1746 return MatchOperand_NoMatch;
1747 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1748 Op->setRegKind(Kind);
1749 Operands.push_back(Op);
1750 hasConsumedDollar = false;
1751 Parser.Lex(); // Eat the register number.
1752 if ((RegKind == MipsOperand::Kind_GPR32) &&
1753 (getLexer().is(AsmToken::LParen))) {
1754 // Check if it is indexed addressing operand.
1755 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1756 Parser.Lex(); // Eat the parenthesis.
1757 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
1758 return MatchOperand_NoMatch;
1759 if (getLexer().isNot(AsmToken::RParen))
1760 return MatchOperand_NoMatch;
1761 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1762 Parser.Lex();
1763 }
1764 return MatchOperand_Success;
1765 }
1766 return MatchOperand_NoMatch;
1767}
1768
1769bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1770 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1771
1772 if (Val < 0)
1773 return false;
1774
1775 switch (Kind) {
1776 default:
1777 return false;
1778 case MipsOperand::Kind_MSA128BRegs:
1779 return Val < 16;
1780 case MipsOperand::Kind_MSA128HRegs:
1781 return Val < 8;
1782 case MipsOperand::Kind_MSA128WRegs:
1783 return Val < 4;
1784 case MipsOperand::Kind_MSA128DRegs:
1785 return Val < 2;
1786 }
1787}
1788
1789MipsAsmParser::OperandMatchResultTy
1790MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1791 int RegKind) {
1792 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1793 SMLoc S = Parser.getTok().getLoc();
1794 std::string RegName;
1795
1796 if (Parser.getTok().isNot(AsmToken::Dollar))
1797 return MatchOperand_NoMatch;
1798
1799 switch (RegKind) {
1800 default:
1801 return MatchOperand_ParseFail;
1802 case MipsOperand::Kind_MSA128BRegs:
1803 case MipsOperand::Kind_MSA128HRegs:
1804 case MipsOperand::Kind_MSA128WRegs:
1805 case MipsOperand::Kind_MSA128DRegs:
1806 break;
1807 }
1808
1809 Parser.Lex(); // Eat the '$'.
1810 if (getLexer().getKind() == AsmToken::Identifier)
1811 RegName = Parser.getTok().getString().lower();
1812 else
1813 return MatchOperand_ParseFail;
1814
1815 int RegNum = matchMSA128RegisterName(RegName);
1816
1817 if (RegNum < 0 || RegNum > 31)
1818 return MatchOperand_ParseFail;
1819
1820 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1821 if (RegVal == -1)
1822 return MatchOperand_ParseFail;
1823
1824 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1825 Op->setRegKind(Kind);
1826 Operands.push_back(Op);
1827
1828 Parser.Lex(); // Eat the register identifier.
1829
1830 // MSA registers may be suffixed with an index in the form of:
1831 // 1) Immediate expression.
1832 // 2) General Purpose Register.
1833 // Examples:
1834 // 1) copy_s.b $29,$w0[0]
1835 // 2) sld.b $w0,$w1[$1]
1836
1837 if (Parser.getTok().isNot(AsmToken::LBrac))
1838 return MatchOperand_Success;
1839
1840 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1841
1842 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1843 Parser.Lex(); // Parse the '[' token.
1844
1845 if (Parser.getTok().is(AsmToken::Dollar)) {
1846 // This must be a GPR.
1847 MipsOperand *RegOp;
1848 SMLoc VIdx = Parser.getTok().getLoc();
1849 Parser.Lex(); // Parse the '$' token.
1850
1851 // GPR have aliases and we must account for that. Example: $30 == $fp
1852 if (getLexer().getKind() == AsmToken::Integer) {
1853 unsigned RegNum = Parser.getTok().getIntVal();
1854 int Reg = matchRegisterByNumber(
1855 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1856 if (Reg == -1) {
1857 Error(VIdx, "invalid general purpose register");
1858 return MatchOperand_ParseFail;
1859 }
1860
1861 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1862 } else if (getLexer().getKind() == AsmToken::Identifier) {
1863 int RegNum = -1;
1864 std::string RegName = Parser.getTok().getString().lower();
1865
1866 RegNum = matchCPURegisterName(RegName);
1867 if (RegNum == -1) {
1868 Error(VIdx, "general purpose register expected");
1869 return MatchOperand_ParseFail;
1870 }
1871 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1872 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1873 } else
1874 return MatchOperand_ParseFail;
1875
1876 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1877 Operands.push_back(RegOp);
1878 Parser.Lex(); // Eat the register identifier.
1879
1880 if (Parser.getTok().isNot(AsmToken::RBrac))
1881 return MatchOperand_ParseFail;
1882
1883 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1884 Parser.Lex(); // Parse the ']' token.
1885
1886 return MatchOperand_Success;
1887 }
1888
1889 // The index must be a constant expression then.
1890 SMLoc VIdx = Parser.getTok().getLoc();
1891 const MCExpr *ImmVal;
1892
1893 if (getParser().parseExpression(ImmVal))
1894 return MatchOperand_ParseFail;
1895
1896 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1897 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1898 Error(VIdx, "invalid immediate value");
1899 return MatchOperand_ParseFail;
1900 }
1901
1902 SMLoc E = Parser.getTok().getEndLoc();
1903
1904 if (Parser.getTok().isNot(AsmToken::RBrac))
1905 return MatchOperand_ParseFail;
1906
1907 bool insve =
1908 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1909 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
1910
1911 // The second vector index of insve instructions is always 0.
1912 if (insve && Operands.size() > 6) {
1913 if (expr->getValue() != 0) {
1914 Error(VIdx, "immediate value must be 0");
1915 return MatchOperand_ParseFail;
1916 }
1917 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1918 } else
1919 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1920
1921 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1922
1923 Parser.Lex(); // Parse the ']' token.
1924
1925 return MatchOperand_Success;
1926}
1927
1928MipsAsmParser::OperandMatchResultTy
1929MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1930 int RegKind) {
1931 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1932
1933 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1934 return MatchOperand_NoMatch;
1935
1936 if (Parser.getTok().isNot(AsmToken::Dollar))
1937 return MatchOperand_ParseFail;
1938
1939 SMLoc S = Parser.getTok().getLoc();
1940
1941 Parser.Lex(); // Eat the '$' symbol.
1942
1943 int RegNum = -1;
1944 if (getLexer().getKind() == AsmToken::Identifier)
1945 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1946 else if (getLexer().getKind() == AsmToken::Integer)
1947 RegNum = Parser.getTok().getIntVal();
1948 else
1949 return MatchOperand_ParseFail;
1950
1951 if (RegNum < 0 || RegNum > 7)
1952 return MatchOperand_ParseFail;
1953
1954 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1955 if (RegVal == -1)
1956 return MatchOperand_ParseFail;
1957
1958 MipsOperand *RegOp =
1959 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1960 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1961 Operands.push_back(RegOp);
1962 Parser.Lex(); // Eat the register identifier.
1963
1964 return MatchOperand_Success;
1965}
1966
1967MipsAsmParser::OperandMatchResultTy
1968MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1969
1970 if (!isGP64())
1971 return MatchOperand_NoMatch;
1972 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
1973}
1974
1975MipsAsmParser::OperandMatchResultTy
1976MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1977 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
1978}
1979
1980MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
Daniel Sanders0c648ba2014-03-31 17:43:46 +00001981 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterd76b2372013-03-21 21:44:16 +00001982
Daniel Sanderse34a1202014-03-31 18:51:43 +00001983 if (isFP64())
1984 return MatchOperand_NoMatch;
1985 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
1986}
1987
1988MipsAsmParser::OperandMatchResultTy
1989MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1990 if (!isFP64())
1991 return MatchOperand_NoMatch;
1992 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
1993}
1994
1995MipsAsmParser::OperandMatchResultTy
1996MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1997 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1998}
1999
2000MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
2001 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2002 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
2003}
2004
2005MipsAsmParser::OperandMatchResultTy
2006MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2007 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
2008}
2009
2010MipsAsmParser::OperandMatchResultTy
2011MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2012 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
2013}
2014
2015MipsAsmParser::OperandMatchResultTy
2016MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2017 // If the first token is not '$' we have an error.
2018 if (Parser.getTok().isNot(AsmToken::Dollar))
2019 return MatchOperand_NoMatch;
2020
2021 SMLoc S = Parser.getTok().getLoc();
2022 Parser.Lex(); // Eat the '$'
2023
2024 const AsmToken &Tok = Parser.getTok(); // Get next token.
2025
2026 if (Tok.isNot(AsmToken::Identifier))
2027 return MatchOperand_NoMatch;
2028
2029 if (!Tok.getIdentifier().startswith("ac"))
2030 return MatchOperand_NoMatch;
2031
2032 StringRef NumString = Tok.getIdentifier().substr(2);
2033
2034 unsigned IntVal;
2035 if (NumString.getAsInteger(10, IntVal))
2036 return MatchOperand_NoMatch;
2037
2038 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
2039
2040 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2041 Op->setRegKind(MipsOperand::Kind_LO32DSP);
2042 Operands.push_back(Op);
2043
2044 Parser.Lex(); // Eat the register number.
2045 return MatchOperand_Success;
2046}
2047
2048MipsAsmParser::OperandMatchResultTy
2049MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2050 // If the first token is not '$' we have an error.
2051 if (Parser.getTok().isNot(AsmToken::Dollar))
2052 return MatchOperand_NoMatch;
2053
2054 SMLoc S = Parser.getTok().getLoc();
2055 Parser.Lex(); // Eat the '$'
2056
2057 const AsmToken &Tok = Parser.getTok(); // Get next token.
2058
2059 if (Tok.isNot(AsmToken::Identifier))
2060 return MatchOperand_NoMatch;
2061
2062 if (!Tok.getIdentifier().startswith("ac"))
2063 return MatchOperand_NoMatch;
2064
2065 StringRef NumString = Tok.getIdentifier().substr(2);
2066
2067 unsigned IntVal;
2068 if (NumString.getAsInteger(10, IntVal))
2069 return MatchOperand_NoMatch;
2070
2071 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
2072
2073 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2074 Op->setRegKind(MipsOperand::Kind_HI32DSP);
2075 Operands.push_back(Op);
2076
2077 Parser.Lex(); // Eat the register number.
2078 return MatchOperand_Success;
2079}
2080
2081MipsAsmParser::OperandMatchResultTy
2082MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2083 // If the first token is not '$' we have an error.
2084 if (Parser.getTok().isNot(AsmToken::Dollar))
2085 return MatchOperand_NoMatch;
2086
2087 SMLoc S = Parser.getTok().getLoc();
2088 Parser.Lex(); // Eat the '$'
2089
2090 const AsmToken &Tok = Parser.getTok(); // Get next token.
2091
2092 if (Tok.isNot(AsmToken::Integer))
2093 return MatchOperand_NoMatch;
2094
2095 unsigned IntVal = Tok.getIntVal();
2096
2097 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2098
2099 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2100 Op->setRegKind(MipsOperand::Kind_COP2);
2101 Operands.push_back(Op);
2102
2103 Parser.Lex(); // Eat the register number.
2104 return MatchOperand_Success;
2105}
2106
2107MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2108 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2109 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
2110}
2111
2112MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2113 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2114 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
2115}
2116
2117MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2118 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2119 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
2120}
2121
2122MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2123 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2124 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
2125}
2126
2127MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2128 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2129 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
2130}
2131
2132bool MipsAsmParser::searchSymbolAlias(
2133 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
2134
Jack Carterd76b2372013-03-21 21:44:16 +00002135 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2136 if (Sym) {
2137 SMLoc S = Parser.getTok().getLoc();
2138 const MCExpr *Expr;
2139 if (Sym->isVariable())
2140 Expr = Sym->getVariableValue();
2141 else
2142 return false;
2143 if (Expr->getKind() == MCExpr::SymbolRef) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00002144 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00002145 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002146 const StringRef DefSymbol = Ref->getSymbol().getName();
2147 if (DefSymbol.startswith("$")) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00002148 int RegNum = -1;
2149 APInt IntVal(32, -1);
2150 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2151 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
2152 isGP64() ? Mips::GPR64RegClassID
2153 : Mips::GPR32RegClassID);
2154 else {
2155 // Lookup for the register with the corresponding name.
2156 switch (Kind) {
2157 case MipsOperand::Kind_AFGR64Regs:
2158 case MipsOperand::Kind_FGR64Regs:
2159 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2160 break;
2161 case MipsOperand::Kind_FGR32Regs:
2162 RegNum = matchFPURegisterName(DefSymbol.substr(1));
2163 break;
2164 case MipsOperand::Kind_GPR64:
2165 case MipsOperand::Kind_GPR32:
2166 default:
2167 RegNum = matchCPURegisterName(DefSymbol.substr(1));
2168 break;
2169 }
2170 if (RegNum > -1)
2171 RegNum = getReg(regKindToRegClass(Kind), RegNum);
2172 }
2173 if (RegNum > -1) {
2174 Parser.Lex();
2175 MipsOperand *op =
2176 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
2177 op->setRegKind(Kind);
2178 Operands.push_back(op);
Jack Carterd76b2372013-03-21 21:44:16 +00002179 return true;
Daniel Sanderse34a1202014-03-31 18:51:43 +00002180 }
Jack Carterd76b2372013-03-21 21:44:16 +00002181 }
2182 } else if (Expr->getKind() == MCExpr::Constant) {
2183 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002184 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2185 MipsOperand *op =
Daniel Sanderse34a1202014-03-31 18:51:43 +00002186 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002187 Operands.push_back(op);
2188 return true;
2189 }
2190 }
2191 return false;
2192}
Jack Carterd0bd6422013-04-18 00:41:53 +00002193
Jack Carter873c7242013-01-12 01:03:14 +00002194MipsAsmParser::OperandMatchResultTy
Daniel Sanderse34a1202014-03-31 18:51:43 +00002195MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2196 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002197}
2198
2199MipsAsmParser::OperandMatchResultTy
Daniel Sanderse34a1202014-03-31 18:51:43 +00002200MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2201 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002202}
2203
Vladimir Medic2b953d02013-10-01 09:48:56 +00002204MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002205MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002206 const MCExpr *IdVal;
2207 // If the first token is '$' we may have register operand.
2208 if (Parser.getTok().is(AsmToken::Dollar))
2209 return MatchOperand_NoMatch;
2210 SMLoc S = Parser.getTok().getLoc();
2211 if (getParser().parseExpression(IdVal))
2212 return MatchOperand_ParseFail;
2213 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002214 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002215 int64_t Val = MCE->getValue();
2216 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2217 Operands.push_back(MipsOperand::CreateImm(
Daniel Sanderse34a1202014-03-31 18:51:43 +00002218 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002219 return MatchOperand_Success;
2220}
2221
Matheus Almeida779c5932013-11-18 12:32:49 +00002222MipsAsmParser::OperandMatchResultTy
Daniel Sanderse34a1202014-03-31 18:51:43 +00002223MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Matheus Almeida779c5932013-11-18 12:32:49 +00002224 switch (getLexer().getKind()) {
2225 default:
2226 return MatchOperand_NoMatch;
2227 case AsmToken::LParen:
2228 case AsmToken::Plus:
2229 case AsmToken::Minus:
2230 case AsmToken::Integer:
2231 break;
2232 }
2233
2234 const MCExpr *Expr;
2235 SMLoc S = Parser.getTok().getLoc();
2236
2237 if (getParser().parseExpression(Expr))
2238 return MatchOperand_ParseFail;
2239
2240 int64_t Val;
2241 if (!Expr->EvaluateAsAbsolute(Val)) {
2242 Error(S, "expected immediate value");
2243 return MatchOperand_ParseFail;
2244 }
2245
2246 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2247 // and because the CPU always adds one to the immediate field, the allowed
2248 // range becomes 1..4. We'll only check the range here and will deal
2249 // with the addition/subtraction when actually decoding/encoding
2250 // the instruction.
2251 if (Val < 1 || Val > 4) {
2252 Error(S, "immediate not in range (1..4)");
2253 return MatchOperand_ParseFail;
2254 }
2255
Jack Carter3b2c96e2014-01-22 23:31:38 +00002256 Operands.push_back(
Daniel Sanderse34a1202014-03-31 18:51:43 +00002257 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002258 return MatchOperand_Success;
2259}
2260
Jack Carterdc1e35d2012-09-06 20:00:02 +00002261MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2262
Vladimir Medic4c299852013-11-06 11:27:05 +00002263 MCSymbolRefExpr::VariantKind VK =
2264 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2265 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2266 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2267 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2268 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2269 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2270 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2271 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2272 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2273 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2274 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2275 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2276 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2277 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2278 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2279 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2280 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2281 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
Daniel Sandersa567da52014-03-31 15:15:02 +00002282 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2283 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2284 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2285 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2286 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2287 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
Vladimir Medic4c299852013-11-06 11:27:05 +00002288 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002289
Daniel Sandersa567da52014-03-31 15:15:02 +00002290 assert (VK != MCSymbolRefExpr::VK_None);
2291
Jack Carterdc1e35d2012-09-06 20:00:02 +00002292 return VK;
2293}
Jack Cartera63b16a2012-09-07 00:23:42 +00002294
Vladimir Medic4c299852013-11-06 11:27:05 +00002295bool MipsAsmParser::ParseInstruction(
2296 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2297 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002298 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002299 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002300 Parser.eatToEndOfStatement();
2301 return Error(NameLoc, "Unknown instruction");
2302 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002303 // First operand in MCInst is instruction mnemonic.
Daniel Sanderse34a1202014-03-31 18:51:43 +00002304 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002305
2306 // Read the remaining operands.
2307 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2308 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002309 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002310 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002311 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002312 return Error(Loc, "unexpected token in argument list");
2313 }
2314
Jack Carterd0bd6422013-04-18 00:41:53 +00002315 while (getLexer().is(AsmToken::Comma)) {
2316 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002317 // Parse and remember the operand.
2318 if (ParseOperand(Operands, Name)) {
2319 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002320 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002321 return Error(Loc, "unexpected token in argument list");
2322 }
2323 }
2324 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002325 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2326 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002327 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002328 return Error(Loc, "unexpected token in argument list");
2329 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002330 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002331 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002332}
2333
Jack Carter0b744b32012-10-04 02:29:46 +00002334bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002335 SMLoc Loc = getLexer().getLoc();
2336 Parser.eatToEndOfStatement();
2337 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002338}
2339
2340bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002341 // Line should look like: ".set noat".
2342 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002343 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002344 // eat noat
2345 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002346 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002347 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2348 reportParseError("unexpected token in statement");
2349 return false;
2350 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002351 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002352 return false;
2353}
Jack Carterd0bd6422013-04-18 00:41:53 +00002354
Jack Carter0b744b32012-10-04 02:29:46 +00002355bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002356 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002357 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002358 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002359 getParser().Lex();
2360 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002361 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002362 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002363 return false;
2364 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002365 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002366 if (getLexer().isNot(AsmToken::Dollar)) {
2367 reportParseError("unexpected token in statement");
2368 return false;
2369 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002370 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002371 const AsmToken &Reg = Parser.getTok();
2372 if (Reg.is(AsmToken::Identifier)) {
2373 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2374 } else if (Reg.is(AsmToken::Integer)) {
2375 AtRegNo = Reg.getIntVal();
2376 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002377 reportParseError("unexpected token in statement");
2378 return false;
2379 }
Jack Carter1ac53222013-02-20 23:11:17 +00002380
Daniel Sanders71a89d922014-03-25 13:01:06 +00002381 if (AtRegNo < 0 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002382 reportParseError("unexpected token in statement");
2383 return false;
2384 }
2385
2386 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002387 reportParseError("unexpected token in statement");
2388 return false;
2389 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002390 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002391
2392 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2393 reportParseError("unexpected token in statement");
2394 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002395 }
2396 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002397 return false;
2398 } else {
2399 reportParseError("unexpected token in statement");
2400 return false;
2401 }
2402}
2403
2404bool MipsAsmParser::parseSetReorderDirective() {
2405 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002406 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002407 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2408 reportParseError("unexpected token in statement");
2409 return false;
2410 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002411 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002412 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002413 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002414 return false;
2415}
2416
2417bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002418 Parser.Lex();
2419 // If this is not the end of the statement, report an error.
2420 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2421 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002422 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002423 }
2424 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002425 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002426 Parser.Lex(); // Consume the EndOfStatement.
2427 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002428}
2429
2430bool MipsAsmParser::parseSetMacroDirective() {
2431 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002432 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002433 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2434 reportParseError("unexpected token in statement");
2435 return false;
2436 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002437 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002438 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002439 return false;
2440}
2441
2442bool MipsAsmParser::parseSetNoMacroDirective() {
2443 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002444 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002445 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2446 reportParseError("`noreorder' must be set before `nomacro'");
2447 return false;
2448 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002449 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002450 reportParseError("`noreorder' must be set before `nomacro'");
2451 return false;
2452 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002453 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002454 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002455 return false;
2456}
Jack Carterd76b2372013-03-21 21:44:16 +00002457
Jack Carter39536722014-01-22 23:08:42 +00002458bool MipsAsmParser::parseSetNoMips16Directive() {
2459 Parser.Lex();
2460 // If this is not the end of the statement, report an error.
2461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2462 reportParseError("unexpected token in statement");
2463 return false;
2464 }
2465 // For now do nothing.
2466 Parser.Lex(); // Consume the EndOfStatement.
2467 return false;
2468}
2469
Jack Carterd76b2372013-03-21 21:44:16 +00002470bool MipsAsmParser::parseSetAssignment() {
2471 StringRef Name;
2472 const MCExpr *Value;
2473
2474 if (Parser.parseIdentifier(Name))
2475 reportParseError("expected identifier after .set");
2476
2477 if (getLexer().isNot(AsmToken::Comma))
2478 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002479 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002480
Jack Carter3b2c96e2014-01-22 23:31:38 +00002481 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002482 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002483
Jack Carterd0bd6422013-04-18 00:41:53 +00002484 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002485 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002486 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002487 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002488 Sym = getContext().GetOrCreateSymbol(Name);
2489 Sym->setVariableValue(Value);
2490
2491 return false;
2492}
Jack Carterd0bd6422013-04-18 00:41:53 +00002493
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002494bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2495 Parser.Lex();
2496 if (getLexer().isNot(AsmToken::EndOfStatement))
2497 return reportParseError("unexpected token in .set directive");
2498
2499 switch(Feature) {
2500 default: llvm_unreachable("Unimplemented feature");
2501 case Mips::FeatureDSP:
2502 setFeatureBits(Mips::FeatureDSP, "dsp");
2503 getTargetStreamer().emitDirectiveSetDsp();
2504 break;
2505 case Mips::FeatureMicroMips:
2506 getTargetStreamer().emitDirectiveSetMicroMips();
2507 break;
2508 case Mips::FeatureMips16:
2509 getTargetStreamer().emitDirectiveSetMips16();
2510 break;
2511 case Mips::FeatureMips32r2:
2512 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2513 getTargetStreamer().emitDirectiveSetMips32R2();
2514 break;
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002515 case Mips::FeatureMips64:
2516 setFeatureBits(Mips::FeatureMips64, "mips64");
2517 getTargetStreamer().emitDirectiveSetMips64();
2518 break;
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002519 case Mips::FeatureMips64r2:
2520 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2521 getTargetStreamer().emitDirectiveSetMips64R2();
2522 break;
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002523 }
2524 return false;
2525}
2526
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002527bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2528 if (!getLexer().is(AsmToken::Dollar))
2529 return false;
2530
2531 Parser.Lex();
2532
2533 const AsmToken &Reg = Parser.getTok();
2534 if (Reg.is(AsmToken::Identifier)) {
2535 RegNum = matchCPURegisterName(Reg.getIdentifier());
2536 } else if (Reg.is(AsmToken::Integer)) {
2537 RegNum = Reg.getIntVal();
2538 } else {
2539 return false;
2540 }
2541
2542 Parser.Lex();
2543 return true;
2544}
2545
2546bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2547 if (getLexer().isNot(AsmToken::Comma)) {
2548 SMLoc Loc = getLexer().getLoc();
2549 Parser.eatToEndOfStatement();
2550 return Error(Loc, ErrorStr);
2551 }
2552
2553 Parser.Lex(); // Eat the comma.
2554 return true;
2555}
2556
2557bool MipsAsmParser::parseDirectiveCPSetup() {
2558 unsigned FuncReg;
2559 unsigned Save;
2560 bool SaveIsReg = true;
2561
2562 if (!parseRegister(FuncReg))
2563 return reportParseError("expected register containing function address");
2564 FuncReg = getGPR(FuncReg);
2565
2566 if (!eatComma("expected comma parsing directive"))
2567 return true;
2568
2569 if (!parseRegister(Save)) {
2570 const AsmToken &Tok = Parser.getTok();
2571 if (Tok.is(AsmToken::Integer)) {
2572 Save = Tok.getIntVal();
2573 SaveIsReg = false;
2574 Parser.Lex();
2575 } else
2576 return reportParseError("expected save register or stack offset");
2577 } else
2578 Save = getGPR(Save);
2579
2580 if (!eatComma("expected comma parsing directive"))
2581 return true;
2582
2583 StringRef Name;
2584 if (Parser.parseIdentifier(Name))
2585 reportParseError("expected identifier");
2586 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2587 unsigned GPReg = getGPR(matchCPURegisterName("gp"));
2588
2589 // FIXME: The code below this point should be in the TargetStreamers.
2590 // Only N32 and N64 emit anything for .cpsetup
2591 // FIXME: We should only emit something for PIC mode too.
2592 if (!isN32() && !isN64())
2593 return false;
2594
2595 MCStreamer &TS = getStreamer();
2596 MCInst Inst;
2597 // Either store the old $gp in a register or on the stack
2598 if (SaveIsReg) {
2599 // move $save, $gpreg
2600 Inst.setOpcode(Mips::DADDu);
2601 Inst.addOperand(MCOperand::CreateReg(Save));
2602 Inst.addOperand(MCOperand::CreateReg(GPReg));
2603 Inst.addOperand(MCOperand::CreateReg(getGPR(0)));
2604 } else {
2605 // sd $gpreg, offset($sp)
2606 Inst.setOpcode(Mips::SD);
2607 Inst.addOperand(MCOperand::CreateReg(GPReg));
2608 Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp"))));
2609 Inst.addOperand(MCOperand::CreateImm(Save));
2610 }
2611 TS.EmitInstruction(Inst, STI);
2612 Inst.clear();
2613
2614 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2615 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI,
2616 getContext());
2617 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2618 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO,
2619 getContext());
2620 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
2621 Inst.setOpcode(Mips::LUi);
2622 Inst.addOperand(MCOperand::CreateReg(GPReg));
2623 Inst.addOperand(MCOperand::CreateExpr(HiExpr));
2624 TS.EmitInstruction(Inst, STI);
2625 Inst.clear();
2626
2627 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
2628 Inst.setOpcode(Mips::ADDiu);
2629 Inst.addOperand(MCOperand::CreateReg(GPReg));
2630 Inst.addOperand(MCOperand::CreateReg(GPReg));
2631 Inst.addOperand(MCOperand::CreateExpr(LoExpr));
2632 TS.EmitInstruction(Inst, STI);
2633 Inst.clear();
2634
2635 // daddu $gp, $gp, $funcreg
2636 Inst.setOpcode(Mips::DADDu);
2637 Inst.addOperand(MCOperand::CreateReg(GPReg));
2638 Inst.addOperand(MCOperand::CreateReg(GPReg));
2639 Inst.addOperand(MCOperand::CreateReg(FuncReg));
2640 TS.EmitInstruction(Inst, STI);
2641 return false;
2642}
2643
Jack Carter0b744b32012-10-04 02:29:46 +00002644bool MipsAsmParser::parseDirectiveSet() {
2645
Jack Carterd0bd6422013-04-18 00:41:53 +00002646 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002647 const AsmToken &Tok = Parser.getTok();
2648
2649 if (Tok.getString() == "noat") {
2650 return parseSetNoAtDirective();
2651 } else if (Tok.getString() == "at") {
2652 return parseSetAtDirective();
2653 } else if (Tok.getString() == "reorder") {
2654 return parseSetReorderDirective();
2655 } else if (Tok.getString() == "noreorder") {
2656 return parseSetNoReorderDirective();
2657 } else if (Tok.getString() == "macro") {
2658 return parseSetMacroDirective();
2659 } else if (Tok.getString() == "nomacro") {
2660 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002661 } else if (Tok.getString() == "mips16") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002662 return parseSetFeature(Mips::FeatureMips16);
Jack Carter0b744b32012-10-04 02:29:46 +00002663 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002664 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002665 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002666 getTargetStreamer().emitDirectiveSetNoMicroMips();
2667 Parser.eatToEndOfStatement();
2668 return false;
2669 } else if (Tok.getString() == "micromips") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002670 return parseSetFeature(Mips::FeatureMicroMips);
Vladimir Medic615b26e2014-03-04 09:54:09 +00002671 } else if (Tok.getString() == "mips32r2") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002672 return parseSetFeature(Mips::FeatureMips32r2);
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002673 } else if (Tok.getString() == "mips64") {
2674 return parseSetFeature(Mips::FeatureMips64);
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002675 } else if (Tok.getString() == "mips64r2") {
2676 return parseSetFeature(Mips::FeatureMips64r2);
Vladimir Medic27c398e2014-03-05 11:05:09 +00002677 } else if (Tok.getString() == "dsp") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002678 return parseSetFeature(Mips::FeatureDSP);
Jack Carterd76b2372013-03-21 21:44:16 +00002679 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002680 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002681 parseSetAssignment();
2682 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002683 }
Jack Carter07c818d2013-01-25 01:31:34 +00002684
Jack Carter0b744b32012-10-04 02:29:46 +00002685 return true;
2686}
2687
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002688/// parseDataDirective
Jack Carter07c818d2013-01-25 01:31:34 +00002689/// ::= .word [ expression (, expression)* ]
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002690bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
Jack Carter07c818d2013-01-25 01:31:34 +00002691 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2692 for (;;) {
2693 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002694 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002695 return true;
2696
2697 getParser().getStreamer().EmitValue(Value, Size);
2698
2699 if (getLexer().is(AsmToken::EndOfStatement))
2700 break;
2701
2702 // FIXME: Improve diagnostic.
2703 if (getLexer().isNot(AsmToken::Comma))
2704 return Error(L, "unexpected token in directive");
2705 Parser.Lex();
2706 }
2707 }
2708
2709 Parser.Lex();
2710 return false;
2711}
2712
Vladimir Medic4c299852013-11-06 11:27:05 +00002713/// parseDirectiveGpWord
2714/// ::= .gpword local_sym
2715bool MipsAsmParser::parseDirectiveGpWord() {
2716 const MCExpr *Value;
2717 // EmitGPRel32Value requires an expression, so we are using base class
2718 // method to evaluate the expression.
2719 if (getParser().parseExpression(Value))
2720 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002721 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002722
Vladimir Medice10c1122013-11-13 13:18:04 +00002723 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002724 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002725 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002726 return false;
2727}
2728
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002729/// parseDirectiveGpDWord
Rafael Espindolab59fb732014-03-28 18:50:26 +00002730/// ::= .gpdword local_sym
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002731bool MipsAsmParser::parseDirectiveGpDWord() {
Rafael Espindolab59fb732014-03-28 18:50:26 +00002732 const MCExpr *Value;
2733 // EmitGPRel64Value requires an expression, so we are using base class
2734 // method to evaluate the expression.
2735 if (getParser().parseExpression(Value))
2736 return true;
2737 getParser().getStreamer().EmitGPRel64Value(Value);
2738
2739 if (getLexer().isNot(AsmToken::EndOfStatement))
2740 return Error(getLexer().getLoc(), "unexpected token in directive");
2741 Parser.Lex(); // Eat EndOfStatement token.
2742 return false;
2743}
2744
Jack Carter0cd3c192014-01-06 23:27:31 +00002745bool MipsAsmParser::parseDirectiveOption() {
2746 // Get the option token.
2747 AsmToken Tok = Parser.getTok();
2748 // At the moment only identifiers are supported.
2749 if (Tok.isNot(AsmToken::Identifier)) {
2750 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2751 Parser.eatToEndOfStatement();
2752 return false;
2753 }
2754
2755 StringRef Option = Tok.getIdentifier();
2756
2757 if (Option == "pic0") {
2758 getTargetStreamer().emitDirectiveOptionPic0();
2759 Parser.Lex();
2760 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2761 Error(Parser.getTok().getLoc(),
2762 "unexpected token in .option pic0 directive");
2763 Parser.eatToEndOfStatement();
2764 }
2765 return false;
2766 }
2767
Matheus Almeidaf79b2812014-03-26 13:40:29 +00002768 if (Option == "pic2") {
2769 getTargetStreamer().emitDirectiveOptionPic2();
2770 Parser.Lex();
2771 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2772 Error(Parser.getTok().getLoc(),
2773 "unexpected token in .option pic2 directive");
2774 Parser.eatToEndOfStatement();
2775 }
2776 return false;
2777 }
2778
Jack Carter0cd3c192014-01-06 23:27:31 +00002779 // Unknown option.
2780 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2781 Parser.eatToEndOfStatement();
2782 return false;
2783}
2784
Jack Carter0b744b32012-10-04 02:29:46 +00002785bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002786 StringRef IDVal = DirectiveID.getString();
2787
Matheus Almeidaab5633b2014-03-26 15:44:18 +00002788 if (IDVal == ".dword") {
2789 parseDataDirective(8, DirectiveID.getLoc());
2790 return false;
2791 }
2792
Jack Carterd0bd6422013-04-18 00:41:53 +00002793 if (IDVal == ".ent") {
2794 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002795 Parser.Lex();
2796 return false;
2797 }
2798
Jack Carter07c818d2013-01-25 01:31:34 +00002799 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002800 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002801 Parser.Lex();
2802 return false;
2803 }
2804
Jack Carter07c818d2013-01-25 01:31:34 +00002805 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002806 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002807 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002808 return false;
2809 }
2810
Jack Carter07c818d2013-01-25 01:31:34 +00002811 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002812 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002813 }
2814
Jack Carter07c818d2013-01-25 01:31:34 +00002815 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002816 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002817 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002818 return false;
2819 }
2820
Jack Carter07c818d2013-01-25 01:31:34 +00002821 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002822 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002823 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002824 return false;
2825 }
2826
Jack Carter07c818d2013-01-25 01:31:34 +00002827 if (IDVal == ".gpword") {
Vladimir Medic4c299852013-11-06 11:27:05 +00002828 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002829 return false;
2830 }
2831
Rafael Espindolab59fb732014-03-28 18:50:26 +00002832 if (IDVal == ".gpdword") {
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002833 parseDirectiveGpDWord();
Rafael Espindolab59fb732014-03-28 18:50:26 +00002834 return false;
2835 }
2836
Jack Carter07c818d2013-01-25 01:31:34 +00002837 if (IDVal == ".word") {
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002838 parseDataDirective(4, DirectiveID.getLoc());
Jack Carter07c818d2013-01-25 01:31:34 +00002839 return false;
2840 }
2841
Jack Carter0cd3c192014-01-06 23:27:31 +00002842 if (IDVal == ".option")
2843 return parseDirectiveOption();
2844
2845 if (IDVal == ".abicalls") {
2846 getTargetStreamer().emitDirectiveAbiCalls();
2847 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2848 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2849 // Clear line
2850 Parser.eatToEndOfStatement();
2851 }
2852 return false;
2853 }
2854
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002855 if (IDVal == ".cpsetup")
2856 return parseDirectiveCPSetup();
2857
Rafael Espindola870c4e92012-01-11 03:56:41 +00002858 return true;
2859}
2860
Rafael Espindola870c4e92012-01-11 03:56:41 +00002861extern "C" void LLVMInitializeMipsAsmParser() {
2862 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2863 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2864 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2865 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2866}
Jack Carterb4dbc172012-09-05 23:34:03 +00002867
2868#define GET_REGISTER_MATCHER
2869#define GET_MATCHER_IMPLEMENTATION
2870#include "MipsGenAsmMatcher.inc"