blob: fa7f7c5cdca7b8c3322f325d0f0479fef845e89f [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
10#include "MCTargetDesc/MipsMCTargetDesc.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000011#include "MipsRegisterInfo.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000012#include "MipsTargetStreamer.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000013#include "llvm/ADT/StringSwitch.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/MC/MCParser/MCAsmLexer.h"
18#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000019#include "llvm/MC/MCStreamer.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000022#include "llvm/MC/MCTargetAsmParser.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000023#include "llvm/Support/TargetRegistry.h"
Jack Carter02593002013-05-28 22:21:05 +000024#include "llvm/ADT/APInt.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000025
26using namespace llvm;
27
Joey Gouly0e76fa72013-09-12 10:28:05 +000028namespace llvm {
29class MCInstrInfo;
30}
31
Rafael Espindola870c4e92012-01-11 03:56:41 +000032namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000033class MipsAssemblerOptions {
34public:
35 MipsAssemblerOptions():
36 aTReg(1), reorder(true), macro(true) {
37 }
Jack Carterb4dbc172012-09-05 23:34:03 +000038
Jack Carter0b744b32012-10-04 02:29:46 +000039 unsigned getATRegNum() {return aTReg;}
40 bool setATReg(unsigned Reg);
41
42 bool isReorder() {return reorder;}
43 void setReorder() {reorder = true;}
44 void setNoreorder() {reorder = false;}
45
46 bool isMacro() {return macro;}
47 void setMacro() {macro = true;}
48 void setNomacro() {macro = false;}
49
50private:
51 unsigned aTReg;
52 bool reorder;
53 bool macro;
54};
55}
56
57namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000058class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000059
Rafael Espindolaa17151a2013-10-08 13:08:17 +000060 MipsTargetStreamer &getTargetStreamer() {
61 MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer();
62 return static_cast<MipsTargetStreamer &>(TS);
63 }
64
Jack Carterb4dbc172012-09-05 23:34:03 +000065 MCSubtargetInfo &STI;
66 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000067 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000068 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000069
Akira Hatanaka7605630c2012-08-17 20:16:42 +000070#define GET_ASSEMBLER_HEADER
71#include "MipsGenAsmMatcher.inc"
72
Chad Rosier49963552012-10-13 00:26:04 +000073 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +000074 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000075 MCStreamer &Out, unsigned &ErrorInfo,
76 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000077
78 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
79
Chad Rosierf0e87202012-10-25 20:41:34 +000080 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
81 SMLoc NameLoc,
Akira Hatanaka7605630c2012-08-17 20:16:42 +000082 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000083
84 bool ParseDirective(AsmToken DirectiveID);
85
Jack Carterb4dbc172012-09-05 23:34:03 +000086 MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +000087 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
88 int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000089
90 MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +000091 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
92 int RegKind);
93
94 MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +000095 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
96 int RegKind);
97
98 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000099 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
100
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000101 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
102
103 MipsAsmParser::OperandMatchResultTy
104 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
105
Jack Carter873c7242013-01-12 01:03:14 +0000106 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000107 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000108
109 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000110 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000111
112 MipsAsmParser::OperandMatchResultTy
113 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
114
115 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +0000116 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000117
Vladimir Medic233dd512013-06-24 10:05:34 +0000118 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
Vladimir Medic643b3982013-07-30 10:12:14 +0000127 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000128 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
129
130 MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +0000131 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
132
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000133 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000134 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000135
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000136 MipsAsmParser::OperandMatchResultTy
137 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
138
139 MipsAsmParser::OperandMatchResultTy
140 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
141
Vladimir Medic05bcde62013-09-16 10:29:42 +0000142 MipsAsmParser::OperandMatchResultTy
143 parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
144
Jack Carter5dc8ac92013-09-25 23:50:44 +0000145 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
Vladimir Medic2b953d02013-10-01 09:48:56 +0000157 MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000158 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
159
160 MipsAsmParser::OperandMatchResultTy
Vladimir Medic2b953d02013-10-01 09:48:56 +0000161 parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
162
Jack Carterd76b2372013-03-21 21:44:16 +0000163 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000164 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000165
Jack Carterb4dbc172012-09-05 23:34:03 +0000166 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
167 StringRef Mnemonic);
168
Jack Carter873c7242013-01-12 01:03:14 +0000169 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000170
171 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000172 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000173
Jack Carter30a59822012-10-04 04:03:53 +0000174 bool needsExpansion(MCInst &Inst);
175
176 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000177 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000178 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000179 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000180 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
182 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000184 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions,
186 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000187 bool reportParseError(StringRef ErrorMsg);
188
Jack Carterb5cf5902013-04-17 00:18:04 +0000189 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000190 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000191
Jack Carterb5cf5902013-04-17 00:18:04 +0000192 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
193
194 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000195 bool parseDirectiveSet();
Rafael Espindolaac4ad252013-10-05 16:42:21 +0000196 bool parseDirectiveMipsHackStocg();
197 bool parseDirectiveMipsHackELFFlags();
Jack Carter0b744b32012-10-04 02:29:46 +0000198
199 bool parseSetAtDirective();
200 bool parseSetNoAtDirective();
201 bool parseSetMacroDirective();
202 bool parseSetNoMacroDirective();
203 bool parseSetReorderDirective();
204 bool parseSetNoReorderDirective();
205
Jack Carterd76b2372013-03-21 21:44:16 +0000206 bool parseSetAssignment();
207
Jack Carter07c818d2013-01-25 01:31:34 +0000208 bool parseDirectiveWord(unsigned Size, SMLoc L);
209
Jack Carterdc1e35d2012-09-06 20:00:02 +0000210 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000211
Jack Carterb4dbc172012-09-05 23:34:03 +0000212 bool isMips64() const {
213 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
214 }
215
Jack Cartera63b16a2012-09-07 00:23:42 +0000216 bool isFP64() const {
217 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
218 }
219
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000220 bool isN64() const {
221 return STI.getFeatureBits() & Mips::FeatureN64;
222 }
223
Jack Carter873c7242013-01-12 01:03:14 +0000224 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000225
Jack Carter1ac53222013-02-20 23:11:17 +0000226 int matchCPURegisterName(StringRef Symbol);
227
Jack Carter873c7242013-01-12 01:03:14 +0000228 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000229
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000230 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000231
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000232 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000233
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000234 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000235
Jack Carter5dc8ac92013-09-25 23:50:44 +0000236 int matchMSA128RegisterName(StringRef Name);
237
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000238 int matchMSA128CtrlRegisterName(StringRef Name);
239
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000240 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000241
Jack Carterd0bd6422013-04-18 00:41:53 +0000242 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000243
Jack Carter1ac53222013-02-20 23:11:17 +0000244 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000245
246 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
247 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000248
249 // Helper function that checks if the value of a vector index is within the
250 // boundaries of accepted values for each RegisterKind
251 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
252 bool validateMSAIndex(int Val, int RegKind);
253
Rafael Espindola870c4e92012-01-11 03:56:41 +0000254public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000255 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
256 const MCInstrInfo &MII)
257 : MCTargetAsmParser(), STI(sti), Parser(parser),
258 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000259 // Initialize the set of available features.
260 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000261 }
262
Jack Carterb4dbc172012-09-05 23:34:03 +0000263 MCAsmParser &getParser() const { return Parser; }
264 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
265
Rafael Espindola870c4e92012-01-11 03:56:41 +0000266};
267}
268
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000269namespace {
270
271/// MipsOperand - Instances of this class represent a parsed Mips machine
272/// instruction.
273class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000274
Jack Carter873c7242013-01-12 01:03:14 +0000275public:
276 enum RegisterKind {
277 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000278 Kind_GPR32,
279 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000280 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000281 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000282 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000283 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000284 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000285 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000286 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000287 Kind_ACC64DSP,
288 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000289 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000290 Kind_COP2,
291 Kind_MSA128BRegs,
292 Kind_MSA128HRegs,
293 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000294 Kind_MSA128DRegs,
295 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000296 };
297
298private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000299 enum KindTy {
300 k_CondCode,
301 k_CoprocNum,
302 k_Immediate,
303 k_Memory,
304 k_PostIndexRegister,
305 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000306 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000307 k_Token
308 } Kind;
309
310 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000311
Eric Christopher8996c5d2013-03-15 00:42:55 +0000312 struct Token {
313 const char *Data;
314 unsigned Length;
315 };
316
317 struct RegOp {
318 unsigned RegNum;
319 RegisterKind Kind;
320 };
321
322 struct ImmOp {
323 const MCExpr *Val;
324 };
325
326 struct MemOp {
327 unsigned Base;
328 const MCExpr *Off;
329 };
330
Jack Carterb4dbc172012-09-05 23:34:03 +0000331 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000332 struct Token Tok;
333 struct RegOp Reg;
334 struct ImmOp Imm;
335 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000336 };
337
338 SMLoc StartLoc, EndLoc;
339
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000340public:
341 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000342 assert(N == 1 && "Invalid number of operands!");
343 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000344 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000345
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000346 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
347 assert(N == 1 && "Invalid number of operands!");
348 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
349 }
350
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000351 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000352 // Add as immediate when possible. Null MCExpr = 0.
353 if (Expr == 0)
354 Inst.addOperand(MCOperand::CreateImm(0));
355 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
356 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
357 else
358 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000359 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000360
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000361 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000362 assert(N == 1 && "Invalid number of operands!");
363 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000364 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000365 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000366
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000367 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000368 assert(N == 2 && "Invalid number of operands!");
369
370 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
371
372 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000373 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000374 }
375
376 bool isReg() const { return Kind == k_Register; }
377 bool isImm() const { return Kind == k_Immediate; }
378 bool isToken() const { return Kind == k_Token; }
379 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000380 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000381 bool isInvNum() const { return Kind == k_Immediate; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000382
383 StringRef getToken() const {
384 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000385 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000386 }
387
388 unsigned getReg() const {
389 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000390 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000391 }
392
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000393 unsigned getPtrReg() const {
394 assert((Kind == k_PtrReg) && "Invalid access!");
395 return Reg.RegNum;
396 }
397
Jack Carter873c7242013-01-12 01:03:14 +0000398 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000399 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000400 Reg.Kind = RegKind;
401 }
402
Jack Carterb4dbc172012-09-05 23:34:03 +0000403 const MCExpr *getImm() const {
404 assert((Kind == k_Immediate) && "Invalid access!");
405 return Imm.Val;
406 }
407
Jack Carterdc1e35d2012-09-06 20:00:02 +0000408 unsigned getMemBase() const {
409 assert((Kind == k_Memory) && "Invalid access!");
410 return Mem.Base;
411 }
412
413 const MCExpr *getMemOff() const {
414 assert((Kind == k_Memory) && "Invalid access!");
415 return Mem.Off;
416 }
417
Jack Carterb4dbc172012-09-05 23:34:03 +0000418 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
419 MipsOperand *Op = new MipsOperand(k_Token);
420 Op->Tok.Data = Str.data();
421 Op->Tok.Length = Str.size();
422 Op->StartLoc = S;
423 Op->EndLoc = S;
424 return Op;
425 }
426
427 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
428 MipsOperand *Op = new MipsOperand(k_Register);
429 Op->Reg.RegNum = RegNum;
430 Op->StartLoc = S;
431 Op->EndLoc = E;
432 return Op;
433 }
434
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000435 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
436 MipsOperand *Op = new MipsOperand(k_PtrReg);
437 Op->Reg.RegNum = RegNum;
438 Op->StartLoc = S;
439 Op->EndLoc = E;
440 return Op;
441 }
442
Jack Carterb4dbc172012-09-05 23:34:03 +0000443 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
444 MipsOperand *Op = new MipsOperand(k_Immediate);
445 Op->Imm.Val = Val;
446 Op->StartLoc = S;
447 Op->EndLoc = E;
448 return Op;
449 }
450
Jack Carterdc1e35d2012-09-06 20:00:02 +0000451 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
452 SMLoc S, SMLoc E) {
453 MipsOperand *Op = new MipsOperand(k_Memory);
454 Op->Mem.Base = Base;
455 Op->Mem.Off = Off;
456 Op->StartLoc = S;
457 Op->EndLoc = E;
458 return Op;
459 }
460
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000461 bool isGPR32Asm() const {
462 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000463 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000464 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000465 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
466 }
467
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000468 bool isGPR64Asm() const {
469 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000470 }
Jack Carter873c7242013-01-12 01:03:14 +0000471
472 bool isHWRegsAsm() const {
473 assert((Kind == k_Register) && "Invalid access!");
474 return Reg.Kind == Kind_HWRegs;
475 }
Jack Carter873c7242013-01-12 01:03:14 +0000476
Jack Carter873c7242013-01-12 01:03:14 +0000477 bool isCCRAsm() const {
478 assert((Kind == k_Register) && "Invalid access!");
479 return Reg.Kind == Kind_CCRRegs;
480 }
481
Vladimir Medic233dd512013-06-24 10:05:34 +0000482 bool isAFGR64Asm() const {
483 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
484 }
485
486 bool isFGR64Asm() const {
487 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
488 }
489
490 bool isFGR32Asm() const {
491 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
492 }
493
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000494 bool isFGRH32Asm() const {
495 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
496 }
497
Vladimir Medic643b3982013-07-30 10:12:14 +0000498 bool isFCCRegsAsm() const {
499 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
500 }
501
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000502 bool isACC64DSPAsm() const {
503 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000504 }
505
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000506 bool isLO32DSPAsm() const {
507 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
508 }
509
510 bool isHI32DSPAsm() const {
511 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
512 }
513
Vladimir Medic05bcde62013-09-16 10:29:42 +0000514 bool isCOP2Asm() const {
515 return Kind == k_Register && Reg.Kind == Kind_COP2;
516 }
517
Jack Carter5dc8ac92013-09-25 23:50:44 +0000518 bool isMSA128BAsm() const {
519 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
520 }
521
522 bool isMSA128HAsm() const {
523 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
524 }
525
526 bool isMSA128WAsm() const {
527 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
528 }
529
530 bool isMSA128DAsm() const {
531 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
532 }
533
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000534 bool isMSA128CRAsm() const {
535 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
536 }
537
Jack Carterb4dbc172012-09-05 23:34:03 +0000538 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000539 SMLoc getStartLoc() const {
540 return StartLoc;
541 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000542 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000543 SMLoc getEndLoc() const {
544 return EndLoc;
545 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000546
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000547 virtual void print(raw_ostream &OS) const {
548 llvm_unreachable("unimplemented!");
549 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000550}; // class MipsOperand
551} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000552
Jack Carter9e65aa32013-03-22 00:05:30 +0000553namespace llvm {
554extern const MCInstrDesc MipsInsts[];
555}
556static const MCInstrDesc &getInstDesc(unsigned Opcode) {
557 return MipsInsts[Opcode];
558}
559
560bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000561 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000562 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
563 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000564 if (MCID.hasDelaySlot() && Options.isReorder()) {
565 // If this instruction has a delay slot and .set reorder is active,
566 // emit a NOP after it.
567 Instructions.push_back(Inst);
568 MCInst NopInst;
569 NopInst.setOpcode(Mips::SLL);
570 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
571 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
572 NopInst.addOperand(MCOperand::CreateImm(0));
573 Instructions.push_back(NopInst);
574 return false;
575 }
576
Jack Carter9e65aa32013-03-22 00:05:30 +0000577 if (MCID.mayLoad() || MCID.mayStore()) {
578 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000579 // reference or immediate we may have to expand instructions.
580 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000581 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000582 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
583 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000584 MCOperand &Op = Inst.getOperand(i);
585 if (Op.isImm()) {
586 int MemOffset = Op.getImm();
587 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000588 // Offset can't exceed 16bit value.
589 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000590 return false;
591 }
592 } else if (Op.isExpr()) {
593 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000594 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000595 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000596 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000597 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000598 // Expand symbol.
599 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000600 return false;
601 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000602 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000603 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000604 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000605 }
606 }
607 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000608 } // for
609 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000610
611 if (needsExpansion(Inst))
612 expandInstruction(Inst, IDLoc, Instructions);
613 else
614 Instructions.push_back(Inst);
615
616 return false;
617}
618
Jack Carter30a59822012-10-04 04:03:53 +0000619bool MipsAsmParser::needsExpansion(MCInst &Inst) {
620
Jack Carterd0bd6422013-04-18 00:41:53 +0000621 switch (Inst.getOpcode()) {
622 case Mips::LoadImm32Reg:
623 case Mips::LoadAddr32Imm:
624 case Mips::LoadAddr32Reg:
625 return true;
626 default:
627 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000628 }
629}
Jack Carter92995f12012-10-06 00:53:28 +0000630
Jack Carter30a59822012-10-04 04:03:53 +0000631void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000632 SmallVectorImpl<MCInst> &Instructions) {
633 switch (Inst.getOpcode()) {
634 case Mips::LoadImm32Reg:
635 return expandLoadImm(Inst, IDLoc, Instructions);
636 case Mips::LoadAddr32Imm:
637 return expandLoadAddressImm(Inst, IDLoc, Instructions);
638 case Mips::LoadAddr32Reg:
639 return expandLoadAddressReg(Inst, IDLoc, Instructions);
640 }
Jack Carter30a59822012-10-04 04:03:53 +0000641}
Jack Carter92995f12012-10-06 00:53:28 +0000642
Jack Carter30a59822012-10-04 04:03:53 +0000643void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000644 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000645 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000646 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000647 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000648 const MCOperand &RegOp = Inst.getOperand(0);
649 assert(RegOp.isReg() && "expected register operand kind");
650
651 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000652 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000653 if (0 <= ImmValue && ImmValue <= 65535) {
654 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000655 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000656 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000657 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000658 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000659 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000660 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000661 } else if (ImmValue < 0 && ImmValue >= -32768) {
662 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000663 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000664 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000665 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000666 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000667 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000668 Instructions.push_back(tmpInst);
669 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000670 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000671 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000672 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000673 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000674 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
675 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000676 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000677 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000678 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000679 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
680 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
681 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
682 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000683 Instructions.push_back(tmpInst);
684 }
685}
Jack Carter92995f12012-10-06 00:53:28 +0000686
Jack Carter543fdf82012-10-09 23:29:45 +0000687void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000688 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000689 MCInst tmpInst;
690 const MCOperand &ImmOp = Inst.getOperand(2);
691 assert(ImmOp.isImm() && "expected immediate operand kind");
692 const MCOperand &SrcRegOp = Inst.getOperand(1);
693 assert(SrcRegOp.isReg() && "expected register operand kind");
694 const MCOperand &DstRegOp = Inst.getOperand(0);
695 assert(DstRegOp.isReg() && "expected register operand kind");
696 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000697 if (-32768 <= ImmValue && ImmValue <= 65535) {
698 // For -32768 <= j <= 65535.
699 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000700 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000701 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
702 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
703 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
704 Instructions.push_back(tmpInst);
705 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000706 // For any other value of j that is representable as a 32-bit integer.
707 // la d,j(s) => lui d,hi16(j)
708 // ori d,d,lo16(j)
709 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000710 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000711 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
712 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
713 Instructions.push_back(tmpInst);
714 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000715 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000716 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
717 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
718 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
719 Instructions.push_back(tmpInst);
720 tmpInst.clear();
721 tmpInst.setOpcode(Mips::ADDu);
722 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
723 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
724 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
725 Instructions.push_back(tmpInst);
726 }
727}
728
729void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000730 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000731 MCInst tmpInst;
732 const MCOperand &ImmOp = Inst.getOperand(1);
733 assert(ImmOp.isImm() && "expected immediate operand kind");
734 const MCOperand &RegOp = Inst.getOperand(0);
735 assert(RegOp.isReg() && "expected register operand kind");
736 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000737 if (-32768 <= ImmValue && ImmValue <= 65535) {
738 // For -32768 <= j <= 65535.
739 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000740 tmpInst.setOpcode(Mips::ADDiu);
741 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000742 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000743 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
744 Instructions.push_back(tmpInst);
745 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000746 // For any other value of j that is representable as a 32-bit integer.
747 // la d,j => lui d,hi16(j)
748 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000749 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000750 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
751 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
752 Instructions.push_back(tmpInst);
753 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000754 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000755 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
756 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
757 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
758 Instructions.push_back(tmpInst);
759 }
760}
761
Jack Carter9e65aa32013-03-22 00:05:30 +0000762void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000763 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000764 const MCSymbolRefExpr *SR;
765 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000766 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000767 const MCExpr *ExprOffset;
768 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000769 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
770 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000771 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000772 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
773 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000774 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000775 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
776 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000777 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000778 if (isImmOpnd) {
779 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
780 ImmOffset = Inst.getOperand(2).getImm();
781 LoOffset = ImmOffset & 0x0000ffff;
782 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000783 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000784 if (LoOffset & 0x8000)
785 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000786 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000787 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000788 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000789 TempInst.setLoc(IDLoc);
790 // 1st instruction in expansion is LUi. For load instruction we can use
791 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000792 // but for stores we must use $at.
793 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000794 TempInst.setOpcode(Mips::LUi);
795 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
796 if (isImmOpnd)
797 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
798 else {
799 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
800 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000801 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
802 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
803 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000804 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000805 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000806 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000807 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000808 }
809 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000810 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000811 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000812 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000813 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000814 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000815 TempInst.setOpcode(Mips::ADDu);
816 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
817 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
818 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
819 Instructions.push_back(TempInst);
820 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000821 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000822 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000823 TempInst.setOpcode(Inst.getOpcode());
824 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
825 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
826 if (isImmOpnd)
827 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
828 else {
829 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000830 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
831 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
832 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000833 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000834 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000835 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000836 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000837 }
838 }
839 Instructions.push_back(TempInst);
840 TempInst.clear();
841}
842
Rafael Espindola870c4e92012-01-11 03:56:41 +0000843bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000844MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000845 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000846 MCStreamer &Out, unsigned &ErrorInfo,
847 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000848 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000849 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000850 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000851 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000852
853 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000854 default:
855 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000856 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000857 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000858 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000859 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000860 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000861 return false;
862 }
863 case Match_MissingFeature:
864 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
865 return true;
866 case Match_InvalidOperand: {
867 SMLoc ErrorLoc = IDLoc;
868 if (ErrorInfo != ~0U) {
869 if (ErrorInfo >= Operands.size())
870 return Error(IDLoc, "too few operands for instruction");
871
Jack Carterd0bd6422013-04-18 00:41:53 +0000872 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
873 if (ErrorLoc == SMLoc())
874 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000875 }
876
877 return Error(ErrorLoc, "invalid operand for instruction");
878 }
879 case Match_MnemonicFail:
880 return Error(IDLoc, "invalid instruction");
881 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000882 return true;
883}
884
Jack Carter1ac53222013-02-20 23:11:17 +0000885int MipsAsmParser::matchCPURegisterName(StringRef Name) {
886 int CC;
887
888 if (Name == "at")
889 return getATReg();
890
891 CC = StringSwitch<unsigned>(Name)
892 .Case("zero", 0)
893 .Case("a0", 4)
894 .Case("a1", 5)
895 .Case("a2", 6)
896 .Case("a3", 7)
897 .Case("v0", 2)
898 .Case("v1", 3)
899 .Case("s0", 16)
900 .Case("s1", 17)
901 .Case("s2", 18)
902 .Case("s3", 19)
903 .Case("s4", 20)
904 .Case("s5", 21)
905 .Case("s6", 22)
906 .Case("s7", 23)
907 .Case("k0", 26)
908 .Case("k1", 27)
909 .Case("sp", 29)
910 .Case("fp", 30)
911 .Case("gp", 28)
912 .Case("ra", 31)
913 .Case("t0", 8)
914 .Case("t1", 9)
915 .Case("t2", 10)
916 .Case("t3", 11)
917 .Case("t4", 12)
918 .Case("t5", 13)
919 .Case("t6", 14)
920 .Case("t7", 15)
921 .Case("t8", 24)
922 .Case("t9", 25)
923 .Default(-1);
924
Jack Carterd0bd6422013-04-18 00:41:53 +0000925 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000926 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
927 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000928 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000929 CC += 4;
930
931 if (CC == -1 && isMips64())
932 CC = StringSwitch<unsigned>(Name)
933 .Case("a4", 8)
934 .Case("a5", 9)
935 .Case("a6", 10)
936 .Case("a7", 11)
937 .Case("kt0", 26)
938 .Case("kt1", 27)
939 .Case("s8", 30)
940 .Default(-1);
941
942 return CC;
943}
Jack Carterd0bd6422013-04-18 00:41:53 +0000944
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000945int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000946
Jack Cartera63b16a2012-09-07 00:23:42 +0000947 if (Name[0] == 'f') {
948 StringRef NumString = Name.substr(1);
949 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000950 if (NumString.getAsInteger(10, IntVal))
951 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000952 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000953 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000954 return IntVal;
955 }
956 return -1;
957}
Jack Cartera63b16a2012-09-07 00:23:42 +0000958
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000959int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
960
961 if (Name.startswith("fcc")) {
962 StringRef NumString = Name.substr(3);
963 unsigned IntVal;
964 if (NumString.getAsInteger(10, IntVal))
965 return -1; // This is not an integer.
966 if (IntVal > 7) // There are only 8 fcc registers.
967 return -1;
968 return IntVal;
969 }
970 return -1;
971}
972
973int MipsAsmParser::matchACRegisterName(StringRef Name) {
974
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000975 if (Name.startswith("ac")) {
976 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000977 unsigned IntVal;
978 if (NumString.getAsInteger(10, IntVal))
979 return -1; // This is not an integer.
980 if (IntVal > 3) // There are only 3 acc registers.
981 return -1;
982 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000983 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000984 return -1;
985}
Jack Carterd0bd6422013-04-18 00:41:53 +0000986
Jack Carter5dc8ac92013-09-25 23:50:44 +0000987int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
988 unsigned IntVal;
989
990 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
991 return -1;
992
993 if (IntVal > 31)
994 return -1;
995
996 return IntVal;
997}
998
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000999int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1000 int CC;
1001
1002 CC = StringSwitch<unsigned>(Name)
1003 .Case("msair", 0)
1004 .Case("msacsr", 1)
1005 .Case("msaaccess", 2)
1006 .Case("msasave", 3)
1007 .Case("msamodify", 4)
1008 .Case("msarequest", 5)
1009 .Case("msamap", 6)
1010 .Case("msaunmap", 7)
1011 .Default(-1);
1012
1013 return CC;
1014}
1015
Vladimir Medic8cd17102013-06-20 11:21:49 +00001016int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1017
Vladimir Medic8cd17102013-06-20 11:21:49 +00001018 int CC;
1019 CC = matchCPURegisterName(Name);
1020 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001021 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1022 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001023 CC = matchFPURegisterName(Name);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001024 //TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001025 if (CC != -1)
1026 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1027 : Mips::FGR32RegClassID);
1028 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001029}
1030
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001031int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001032
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001033 switch (RegKind) {
1034 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
1035 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
1036 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
1037 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001038 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001039 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
1040 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
1041 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
1042 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
1043 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
Jack Carter5dc8ac92013-09-25 23:50:44 +00001044 case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
1045 case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
1046 case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
1047 case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001048 case MipsOperand::Kind_MSA128CtrlRegs: return Mips::MSACtrlRegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001049 default :return -1;
1050 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001051
Jack Cartera63b16a2012-09-07 00:23:42 +00001052}
Jack Carterb4dbc172012-09-05 23:34:03 +00001053
Jack Carter0b744b32012-10-04 02:29:46 +00001054bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1055 if (Reg > 31)
1056 return false;
1057
1058 aTReg = Reg;
1059 return true;
1060}
1061
Jack Carter1ac53222013-02-20 23:11:17 +00001062int MipsAsmParser::getATReg() {
1063 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +00001064}
1065
Jack Carterd0bd6422013-04-18 00:41:53 +00001066unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001067 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001068}
1069
Jack Carter873c7242013-01-12 01:03:14 +00001070int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001071 if (RegNum >
1072 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001073 return -1;
1074
Jack Carter873c7242013-01-12 01:03:14 +00001075 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001076}
1077
Jack Carter873c7242013-01-12 01:03:14 +00001078int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001079 const AsmToken &Tok = Parser.getTok();
1080 int RegNum = -1;
1081
1082 if (Tok.is(AsmToken::Identifier)) {
1083 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001084 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001085 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001086 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001087 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001088 return RegNum;
1089}
1090
Jack Carterd0bd6422013-04-18 00:41:53 +00001091bool MipsAsmParser::tryParseRegisterOperand(
1092 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001093
1094 SMLoc S = Parser.getTok().getLoc();
1095 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001096
Jack Carter873c7242013-01-12 01:03:14 +00001097 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001098 if (RegNo == -1)
1099 return true;
1100
Jack Carter873c7242013-01-12 01:03:14 +00001101 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +00001102 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001103 Parser.Lex(); // Eat register token.
1104 return false;
1105}
1106
1107bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1108 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001109 // Check if the current operand has a custom associated parser, if so, try to
1110 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001111 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1112 if (ResTy == MatchOperand_Success)
1113 return false;
1114 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1115 // there was a match, but an error occurred, in which case, just return that
1116 // the operand parsing failed.
1117 if (ResTy == MatchOperand_ParseFail)
1118 return true;
1119
1120 switch (getLexer().getKind()) {
1121 default:
1122 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1123 return true;
1124 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001125 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001126 SMLoc S = Parser.getTok().getLoc();
1127 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001128 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001129 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001130 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001131 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001132 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001133 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001134 if (getLexer().isNot(AsmToken::Dollar))
1135 return true;
1136
Jack Carterd0bd6422013-04-18 00:41:53 +00001137 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001138 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001139 return true;
1140
1141 if (!getLexer().is(AsmToken::RParen))
1142 return true;
1143
1144 S = Parser.getTok().getLoc();
1145 Operands.push_back(MipsOperand::CreateToken(")", S));
1146 Parser.Lex();
1147 }
1148 return false;
1149 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001150 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001151 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001152 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001153 return true;
1154
Jack Carter873c7242013-01-12 01:03:14 +00001155 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001156
Benjamin Kramerfa530572012-09-07 09:47:42 +00001157 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001158
Jack Carterd0bd6422013-04-18 00:41:53 +00001159 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001160 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001161 getContext());
1162
1163 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1164 return false;
1165 }
1166 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001167 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001168 // we need to assigne the propper RegisterKind.
1169 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1170 return false;
1171 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001172 case AsmToken::LParen:
1173 case AsmToken::Minus:
1174 case AsmToken::Plus:
1175 case AsmToken::Integer:
1176 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001177 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001178 const MCExpr *IdVal;
1179 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001180 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001181 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001182 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001183 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1184 return false;
1185 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001186 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001187 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001188 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001189 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001190 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001191 return true;
1192
Jack Carter873c7242013-01-12 01:03:14 +00001193 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1194
Jack Carterdc1e35d2012-09-06 20:00:02 +00001195 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1196 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001197 } // case AsmToken::Percent
1198 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001199 return true;
1200}
1201
Jack Carterb5cf5902013-04-17 00:18:04 +00001202const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1203 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001204 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001205 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001206 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001207 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001208 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001209 short Val = MCE->getValue();
1210 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001211 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001212 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001213 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001214 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001215 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001216 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001217 if (LoSign)
1218 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001219 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001220 } else {
1221 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001222 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001223 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001224 }
1225
Jack Carterb5cf5902013-04-17 00:18:04 +00001226 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001227 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001228 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001229 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001230 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001231 return Res;
1232 }
1233
1234 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001235 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1236 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001237 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1238 return Res;
1239 }
1240
1241 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001242 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1243 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1244 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001245 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001246 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001247 return Expr;
1248}
1249
1250bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1251
1252 switch (Expr->getKind()) {
1253 case MCExpr::Constant:
1254 return true;
1255 case MCExpr::SymbolRef:
1256 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1257 case MCExpr::Binary:
1258 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1259 if (!isEvaluated(BE->getLHS()))
1260 return false;
1261 return isEvaluated(BE->getRHS());
1262 }
1263 case MCExpr::Unary:
1264 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1265 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001266 return false;
1267 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001268 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001269}
Jack Carterd0bd6422013-04-18 00:41:53 +00001270
Jack Carterb5cf5902013-04-17 00:18:04 +00001271bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001272 Parser.Lex(); // Eat the % token.
1273 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001274 if (Tok.isNot(AsmToken::Identifier))
1275 return true;
1276
1277 std::string Str = Tok.getIdentifier().str();
1278
Jack Carterd0bd6422013-04-18 00:41:53 +00001279 Parser.Lex(); // Eat the identifier.
1280 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001281 const MCExpr *IdVal;
1282 SMLoc EndLoc;
1283
1284 if (getLexer().getKind() == AsmToken::LParen) {
1285 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001286 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001287 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001288 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001289 const AsmToken &nextTok = Parser.getTok();
1290 if (nextTok.isNot(AsmToken::Identifier))
1291 return true;
1292 Str += "(%";
1293 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001294 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001295 if (getLexer().getKind() != AsmToken::LParen)
1296 return true;
1297 } else
1298 break;
1299 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001300 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001301 return true;
1302
1303 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001304 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001305
1306 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001307 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001308
Jack Carterd0bd6422013-04-18 00:41:53 +00001309 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001310 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001311}
1312
Jack Carterb4dbc172012-09-05 23:34:03 +00001313bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1314 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001315 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001316 RegNo = tryParseRegister(isMips64());
1317 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001318 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001319}
1320
Jack Carterb5cf5902013-04-17 00:18:04 +00001321bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001322 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001323 bool Result = true;
1324
1325 while (getLexer().getKind() == AsmToken::LParen)
1326 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001327
Jack Carterd0bd6422013-04-18 00:41:53 +00001328 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001329 default:
1330 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001331 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001332 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001333 case AsmToken::Integer:
1334 case AsmToken::Minus:
1335 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001336 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001337 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001338 else
1339 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001340 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001341 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001342 break;
Jack Carter873c7242013-01-12 01:03:14 +00001343 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001344 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001345 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001346 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001347}
1348
Jack Carterb4dbc172012-09-05 23:34:03 +00001349MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001350 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001351
1352 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001353 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001354 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001355 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001356 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001357 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001358
Jack Carterb5cf5902013-04-17 00:18:04 +00001359 if (getLexer().getKind() == AsmToken::LParen) {
1360 Parser.Lex();
1361 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001362 }
1363
Jack Carterb5cf5902013-04-17 00:18:04 +00001364 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001365 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001366 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001367
Jack Carterd0bd6422013-04-18 00:41:53 +00001368 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001369 if (Tok.isNot(AsmToken::LParen)) {
1370 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1371 if (Mnemonic->getToken() == "la") {
1372 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001373 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001374 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1375 return MatchOperand_Success;
1376 }
1377 if (Tok.is(AsmToken::EndOfStatement)) {
1378 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001379 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001380
Jack Carterd0bd6422013-04-18 00:41:53 +00001381 // Zero register assumed, add a memory operand with ZERO as its base.
1382 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1383 : Mips::ZERO,
1384 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001385 return MatchOperand_Success;
1386 }
1387 Error(Parser.getTok().getLoc(), "'(' expected");
1388 return MatchOperand_ParseFail;
1389 }
1390
Jack Carterd0bd6422013-04-18 00:41:53 +00001391 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001392 }
1393
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001394 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1395 (int) MipsOperand::Kind_GPR32);
1396 if (Res != MatchOperand_Success)
1397 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001398
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001399 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001400 Error(Parser.getTok().getLoc(), "')' expected");
1401 return MatchOperand_ParseFail;
1402 }
1403
Jack Carter873c7242013-01-12 01:03:14 +00001404 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1405
Jack Carterd0bd6422013-04-18 00:41:53 +00001406 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001407
1408 if (IdVal == 0)
1409 IdVal = MCConstantExpr::Create(0, getContext());
1410
Jack Carterd0bd6422013-04-18 00:41:53 +00001411 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001412 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1413 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001414 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001415 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001416 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001417 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1418 int64_t Imm;
1419 if (IdVal->EvaluateAsAbsolute(Imm))
1420 IdVal = MCConstantExpr::Create(Imm, getContext());
1421 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1422 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1423 getContext());
1424 }
1425
Jack Carterdc1e35d2012-09-06 20:00:02 +00001426 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1427 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001428 return MatchOperand_Success;
1429}
1430
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001431bool
1432MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1433 int RegKind) {
1434 // If the first token is not '$' we have an error.
1435 if (Parser.getTok().isNot(AsmToken::Dollar))
1436 return false;
1437
1438 SMLoc S = Parser.getTok().getLoc();
1439 Parser.Lex();
1440 AsmToken::TokenKind TkKind = getLexer().getKind();
1441 int Reg;
1442
1443 if (TkKind == AsmToken::Integer) {
1444 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1445 regKindToRegClass(RegKind));
1446 if (Reg == -1)
1447 return false;
1448 } else if (TkKind == AsmToken::Identifier) {
1449 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1450 return false;
1451 Reg = getReg(regKindToRegClass(RegKind), Reg);
1452 } else {
1453 return false;
1454 }
1455
1456 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1457 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1458 Operands.push_back(Op);
1459 Parser.Lex();
1460 return true;
1461}
1462
1463MipsAsmParser::OperandMatchResultTy
1464MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1465 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1466 MipsOperand::Kind_GPR32;
1467
1468 // Parse index register.
1469 if (!parsePtrReg(Operands, RegKind))
1470 return MatchOperand_NoMatch;
1471
1472 // Parse '('.
1473 if (Parser.getTok().isNot(AsmToken::LParen))
1474 return MatchOperand_NoMatch;
1475
1476 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1477 Parser.Lex();
1478
1479 // Parse base register.
1480 if (!parsePtrReg(Operands, RegKind))
1481 return MatchOperand_NoMatch;
1482
1483 // Parse ')'.
1484 if (Parser.getTok().isNot(AsmToken::RParen))
1485 return MatchOperand_NoMatch;
1486
1487 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1488 Parser.Lex();
1489
1490 return MatchOperand_Success;
1491}
1492
Jack Carter873c7242013-01-12 01:03:14 +00001493MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001494MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1495 int RegKind) {
1496 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001497 if (getLexer().getKind() == AsmToken::Identifier
1498 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001499 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001500 return MatchOperand_Success;
1501 return MatchOperand_NoMatch;
1502 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001503 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001504 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001505 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001506 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001507 if (!hasConsumedDollar) {
1508 Parser.Lex(); // Eat the '$'
1509 hasConsumedDollar = true;
1510 }
1511 if (getLexer().getKind() == AsmToken::Identifier) {
1512 int RegNum = -1;
1513 std::string RegName = Parser.getTok().getString().lower();
1514 // Match register by name
1515 switch (RegKind) {
1516 case MipsOperand::Kind_GPR32:
1517 case MipsOperand::Kind_GPR64:
1518 RegNum = matchCPURegisterName(RegName);
1519 break;
1520 case MipsOperand::Kind_AFGR64Regs:
1521 case MipsOperand::Kind_FGR64Regs:
1522 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001523 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001524 RegNum = matchFPURegisterName(RegName);
1525 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1526 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001527 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1528 && !isFP64())
1529 if (RegNum != -1 && RegNum %2 != 0)
1530 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001531 break;
1532 case MipsOperand::Kind_FCCRegs:
1533 RegNum = matchFCCRegisterName(RegName);
1534 break;
1535 case MipsOperand::Kind_ACC64DSP:
1536 RegNum = matchACRegisterName(RegName);
1537 break;
1538 default: break; // No match, value is set to -1.
1539 }
1540 // No match found, return _NoMatch to give a chance to other round.
1541 if (RegNum < 0)
1542 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001543
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001544 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1545 if (RegVal == -1)
1546 return MatchOperand_NoMatch;
1547
1548 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1549 Parser.getTok().getLoc());
1550 Op->setRegKind(Kind);
1551 Operands.push_back(Op);
1552 hasConsumedDollar = false;
1553 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001554 return MatchOperand_Success;
1555 } else if (getLexer().getKind() == AsmToken::Integer) {
1556 unsigned RegNum = Parser.getTok().getIntVal();
1557 if (Kind == MipsOperand::Kind_HWRegs) {
1558 if (RegNum != 29)
1559 return MatchOperand_NoMatch;
1560 // Only hwreg 29 is supported, found at index 0.
1561 RegNum = 0;
1562 }
1563 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1564 if (Reg == -1)
1565 return MatchOperand_NoMatch;
1566 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1567 Op->setRegKind(Kind);
1568 Operands.push_back(Op);
1569 hasConsumedDollar = false;
1570 Parser.Lex(); // Eat the register number.
1571 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001572 && (getLexer().is(AsmToken::LParen))) {
1573 // Check if it is indexed addressing operand.
1574 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1575 Parser.Lex(); // Eat the parenthesis.
1576 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1577 return MatchOperand_NoMatch;
1578 if (getLexer().isNot(AsmToken::RParen))
1579 return MatchOperand_NoMatch;
1580 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1581 Parser.Lex();
1582 }
Jack Carter873c7242013-01-12 01:03:14 +00001583 return MatchOperand_Success;
1584 }
1585 return MatchOperand_NoMatch;
1586}
Vladimir Medic64828a12013-07-16 10:07:14 +00001587
Matheus Almeidab74293d2013-10-14 11:49:30 +00001588bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1589 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1590
1591 if (Val < 0)
1592 return false;
1593
1594 switch (Kind) {
1595 default:
1596 return false;
1597 case MipsOperand::Kind_MSA128BRegs:
1598 return Val < 16;
1599 case MipsOperand::Kind_MSA128HRegs:
1600 return Val < 8;
1601 case MipsOperand::Kind_MSA128WRegs:
1602 return Val < 4;
1603 case MipsOperand::Kind_MSA128DRegs:
1604 return Val < 2;
1605 }
1606}
1607
Vladimir Medic8cd17102013-06-20 11:21:49 +00001608MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +00001609MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1610 int RegKind) {
1611 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1612 SMLoc S = Parser.getTok().getLoc();
1613 std::string RegName;
1614
1615 if (Parser.getTok().isNot(AsmToken::Dollar))
1616 return MatchOperand_NoMatch;
1617
1618 switch (RegKind) {
1619 default:
1620 return MatchOperand_ParseFail;
1621 case MipsOperand::Kind_MSA128BRegs:
1622 case MipsOperand::Kind_MSA128HRegs:
1623 case MipsOperand::Kind_MSA128WRegs:
1624 case MipsOperand::Kind_MSA128DRegs:
1625 break;
1626 }
1627
1628 Parser.Lex(); // Eat the '$'.
1629 if (getLexer().getKind() == AsmToken::Identifier)
1630 RegName = Parser.getTok().getString().lower();
1631 else
1632 return MatchOperand_ParseFail;
1633
1634 int RegNum = matchMSA128RegisterName(RegName);
1635
1636 if (RegNum < 0 || RegNum > 31)
1637 return MatchOperand_ParseFail;
1638
1639 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1640 if (RegVal == -1)
1641 return MatchOperand_ParseFail;
1642
1643 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1644 Parser.getTok().getLoc());
1645 Op->setRegKind(Kind);
1646 Operands.push_back(Op);
1647
1648 Parser.Lex(); // Eat the register identifier.
1649
Matheus Almeidab74293d2013-10-14 11:49:30 +00001650 // MSA registers may be suffixed with an index in the form of:
1651 // 1) Immediate expression.
1652 // 2) General Purpose Register.
1653 // Examples:
1654 // 1) copy_s.b $29,$w0[0]
1655 // 2) sld.b $w0,$w1[$1]
1656
1657 if (Parser.getTok().isNot(AsmToken::LBrac))
1658 return MatchOperand_Success;
1659
1660 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1661
1662 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1663 Parser.Lex(); // Parse the '[' token.
1664
1665 if (Parser.getTok().is(AsmToken::Dollar)) {
1666 // This must be a GPR.
1667 MipsOperand *RegOp;
1668 SMLoc VIdx = Parser.getTok().getLoc();
1669 Parser.Lex(); // Parse the '$' token.
1670
1671 // GPR have aliases and we must account for that. Example: $30 == $fp
1672 if (getLexer().getKind() == AsmToken::Integer) {
1673 unsigned RegNum = Parser.getTok().getIntVal();
1674 int Reg = matchRegisterByNumber(
1675 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1676 if (Reg == -1) {
1677 Error(VIdx, "invalid general purpose register");
1678 return MatchOperand_ParseFail;
1679 }
1680
1681 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1682 } else if (getLexer().getKind() == AsmToken::Identifier) {
1683 int RegNum = -1;
1684 std::string RegName = Parser.getTok().getString().lower();
1685
1686 RegNum = matchCPURegisterName(RegName);
1687 if (RegNum == -1) {
1688 Error(VIdx, "general purpose register expected");
1689 return MatchOperand_ParseFail;
1690 }
1691 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1692 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1693 } else
1694 return MatchOperand_ParseFail;
1695
1696 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1697 Operands.push_back(RegOp);
1698 Parser.Lex(); // Eat the register identifier.
1699
1700 if (Parser.getTok().isNot(AsmToken::RBrac))
1701 return MatchOperand_ParseFail;
1702
1703 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1704 Parser.Lex(); // Parse the ']' token.
1705
1706 return MatchOperand_Success;
1707 }
1708
1709 // The index must be a constant expression then.
1710 SMLoc VIdx = Parser.getTok().getLoc();
1711 const MCExpr *ImmVal;
1712
1713 if (getParser().parseExpression(ImmVal))
1714 return MatchOperand_ParseFail;
1715
1716 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1717 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1718 Error(VIdx, "invalid immediate value");
1719 return MatchOperand_ParseFail;
1720 }
1721
1722 SMLoc E = Parser.getTok().getEndLoc();
1723
1724 if (Parser.getTok().isNot(AsmToken::RBrac))
1725 return MatchOperand_ParseFail;
1726
1727 bool insve = Mnemonic->getToken() == "insve.b" ||
1728 Mnemonic->getToken() == "insve.h" ||
1729 Mnemonic->getToken() == "insve.w" ||
1730 Mnemonic->getToken() == "insve.d";
1731
1732 // The second vector index of insve instructions is always 0.
1733 if (insve && Operands.size() > 6) {
1734 if (expr->getValue() != 0) {
1735 Error(VIdx, "immediate value must be 0");
1736 return MatchOperand_ParseFail;
1737 }
1738 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1739 } else
1740 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1741
1742 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1743
1744 Parser.Lex(); // Parse the ']' token.
1745
Jack Carter5dc8ac92013-09-25 23:50:44 +00001746 return MatchOperand_Success;
1747}
1748
1749MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001750MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1751 int RegKind) {
1752 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1753
1754 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1755 return MatchOperand_NoMatch;
1756
1757 if (Parser.getTok().isNot(AsmToken::Dollar))
1758 return MatchOperand_ParseFail;
1759
1760 SMLoc S = Parser.getTok().getLoc();
1761
1762 Parser.Lex(); // Eat the '$' symbol.
1763
1764 int RegNum = -1;
1765 if (getLexer().getKind() == AsmToken::Identifier)
1766 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1767 else if (getLexer().getKind() == AsmToken::Integer)
1768 RegNum = Parser.getTok().getIntVal();
1769 else
1770 return MatchOperand_ParseFail;
1771
1772 if (RegNum < 0 || RegNum > 7)
1773 return MatchOperand_ParseFail;
1774
1775 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1776 if (RegVal == -1)
1777 return MatchOperand_ParseFail;
1778
1779 MipsOperand *RegOp = MipsOperand::CreateReg(RegVal, S,
1780 Parser.getTok().getLoc());
1781 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1782 Operands.push_back(RegOp);
1783 Parser.Lex(); // Eat the register identifier.
1784
1785 return MatchOperand_Success;
1786}
1787
1788MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001789MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001790
1791 if (!isMips64())
1792 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001793 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001794}
1795
1796MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001797MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1798 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001799}
Jack Carter873c7242013-01-12 01:03:14 +00001800
Vladimir Medic233dd512013-06-24 10:05:34 +00001801MipsAsmParser::OperandMatchResultTy
1802MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1803
1804 if (isFP64())
1805 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001806 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1807}
1808
1809MipsAsmParser::OperandMatchResultTy
1810MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1811 if (!isFP64())
1812 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001813 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1814}
1815
1816MipsAsmParser::OperandMatchResultTy
1817MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001818 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1819}
1820
Vladimir Medic643b3982013-07-30 10:12:14 +00001821MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001822MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1823 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1824}
1825
1826MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001827MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001828 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001829}
1830
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001831MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001832MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001833 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001834}
1835
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001836MipsAsmParser::OperandMatchResultTy
1837MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1838 // If the first token is not '$' we have an error.
1839 if (Parser.getTok().isNot(AsmToken::Dollar))
1840 return MatchOperand_NoMatch;
1841
1842 SMLoc S = Parser.getTok().getLoc();
1843 Parser.Lex(); // Eat the '$'
1844
1845 const AsmToken &Tok = Parser.getTok(); // Get next token.
1846
1847 if (Tok.isNot(AsmToken::Identifier))
1848 return MatchOperand_NoMatch;
1849
1850 if (!Tok.getIdentifier().startswith("ac"))
1851 return MatchOperand_NoMatch;
1852
1853 StringRef NumString = Tok.getIdentifier().substr(2);
1854
1855 unsigned IntVal;
1856 if (NumString.getAsInteger(10, IntVal))
1857 return MatchOperand_NoMatch;
1858
1859 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1860
1861 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1862 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1863 Operands.push_back(Op);
1864
1865 Parser.Lex(); // Eat the register number.
1866 return MatchOperand_Success;
1867}
1868
1869MipsAsmParser::OperandMatchResultTy
1870MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1871 // If the first token is not '$' we have an error.
1872 if (Parser.getTok().isNot(AsmToken::Dollar))
1873 return MatchOperand_NoMatch;
1874
1875 SMLoc S = Parser.getTok().getLoc();
1876 Parser.Lex(); // Eat the '$'
1877
1878 const AsmToken &Tok = Parser.getTok(); // Get next token.
1879
1880 if (Tok.isNot(AsmToken::Identifier))
1881 return MatchOperand_NoMatch;
1882
1883 if (!Tok.getIdentifier().startswith("ac"))
1884 return MatchOperand_NoMatch;
1885
1886 StringRef NumString = Tok.getIdentifier().substr(2);
1887
1888 unsigned IntVal;
1889 if (NumString.getAsInteger(10, IntVal))
1890 return MatchOperand_NoMatch;
1891
1892 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1893
1894 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1895 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1896 Operands.push_back(Op);
1897
1898 Parser.Lex(); // Eat the register number.
1899 return MatchOperand_Success;
1900}
1901
Vladimir Medic05bcde62013-09-16 10:29:42 +00001902MipsAsmParser::OperandMatchResultTy
1903MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1904 // If the first token is not '$' we have an error.
1905 if (Parser.getTok().isNot(AsmToken::Dollar))
1906 return MatchOperand_NoMatch;
1907
1908 SMLoc S = Parser.getTok().getLoc();
1909 Parser.Lex(); // Eat the '$'
1910
1911 const AsmToken &Tok = Parser.getTok(); // Get next token.
1912
1913 if (Tok.isNot(AsmToken::Integer))
1914 return MatchOperand_NoMatch;
1915
1916 unsigned IntVal = Tok.getIntVal();
1917
1918 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1919
1920 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1921 Op->setRegKind(MipsOperand::Kind_COP2);
1922 Operands.push_back(Op);
1923
1924 Parser.Lex(); // Eat the register number.
1925 return MatchOperand_Success;
1926}
1927
Jack Carter5dc8ac92013-09-25 23:50:44 +00001928MipsAsmParser::OperandMatchResultTy
1929MipsAsmParser::parseMSA128BRegs(
1930 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1931 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
1932}
1933
1934MipsAsmParser::OperandMatchResultTy
1935MipsAsmParser::parseMSA128HRegs(
1936 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1937 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
1938}
1939
1940MipsAsmParser::OperandMatchResultTy
1941MipsAsmParser::parseMSA128WRegs(
1942 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1943 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
1944}
1945
1946MipsAsmParser::OperandMatchResultTy
1947MipsAsmParser::parseMSA128DRegs(
1948 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1949 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
1950}
1951
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001952MipsAsmParser::OperandMatchResultTy
1953MipsAsmParser::parseMSA128CtrlRegs(
1954 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1955 return parseMSACtrlRegs(Operands, (int) MipsOperand::Kind_MSA128CtrlRegs);
1956}
1957
Jack Carterd0bd6422013-04-18 00:41:53 +00001958bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001959 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001960
1961 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1962 if (Sym) {
1963 SMLoc S = Parser.getTok().getLoc();
1964 const MCExpr *Expr;
1965 if (Sym->isVariable())
1966 Expr = Sym->getVariableValue();
1967 else
1968 return false;
1969 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001970 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001971 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1972 const StringRef DefSymbol = Ref->getSymbol().getName();
1973 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001974 int RegNum = -1;
1975 APInt IntVal(32, -1);
1976 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1977 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001978 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001979 ? Mips::GPR64RegClassID
1980 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001981 else {
1982 // Lookup for the register with the corresponding name.
1983 switch (Kind) {
1984 case MipsOperand::Kind_AFGR64Regs:
1985 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001986 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001987 break;
1988 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001989 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001990 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001991 case MipsOperand::Kind_GPR64:
1992 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001993 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001994 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001995 break;
1996 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001997 if (RegNum > -1)
1998 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001999 }
Jack Carterd76b2372013-03-21 21:44:16 +00002000 if (RegNum > -1) {
2001 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002002 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
2003 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002004 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002005 Operands.push_back(op);
2006 return true;
2007 }
2008 }
2009 } else if (Expr->getKind() == MCExpr::Constant) {
2010 Parser.Lex();
2011 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00002012 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00002013 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002014 Operands.push_back(op);
2015 return true;
2016 }
2017 }
2018 return false;
2019}
Jack Carterd0bd6422013-04-18 00:41:53 +00002020
Jack Carter873c7242013-01-12 01:03:14 +00002021MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00002022MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002023 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002024}
2025
2026MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00002027MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002028 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002029}
2030
Vladimir Medic2b953d02013-10-01 09:48:56 +00002031MipsAsmParser::OperandMatchResultTy
2032MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2033 const MCExpr *IdVal;
2034 // If the first token is '$' we may have register operand.
2035 if (Parser.getTok().is(AsmToken::Dollar))
2036 return MatchOperand_NoMatch;
2037 SMLoc S = Parser.getTok().getLoc();
2038 if (getParser().parseExpression(IdVal))
2039 return MatchOperand_ParseFail;
2040 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2041 assert( MCE && "Unexpected MCExpr type.");
2042 int64_t Val = MCE->getValue();
2043 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2044 Operands.push_back(MipsOperand::CreateImm(
2045 MCConstantExpr::Create(0 - Val, getContext()), S, E));
2046 return MatchOperand_Success;
2047}
2048
Jack Carterdc1e35d2012-09-06 20:00:02 +00002049MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2050
2051 MCSymbolRefExpr::VariantKind VK
2052 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2053 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2054 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2055 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2056 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2057 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2058 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2059 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2060 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2061 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2062 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2063 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2064 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2065 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2066 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2067 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2068 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2069 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2070 .Default(MCSymbolRefExpr::VK_None);
2071
2072 return VK;
2073}
Jack Cartera63b16a2012-09-07 00:23:42 +00002074
Rafael Espindola870c4e92012-01-11 03:56:41 +00002075bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00002076ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00002077 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002078 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002079 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002080 Parser.eatToEndOfStatement();
2081 return Error(NameLoc, "Unknown instruction");
2082 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002083 // First operand in MCInst is instruction mnemonic.
2084 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002085
2086 // Read the remaining operands.
2087 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2088 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002089 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002090 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002091 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002092 return Error(Loc, "unexpected token in argument list");
2093 }
2094
Jack Carterd0bd6422013-04-18 00:41:53 +00002095 while (getLexer().is(AsmToken::Comma)) {
2096 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002097 // Parse and remember the operand.
2098 if (ParseOperand(Operands, Name)) {
2099 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002100 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002101 return Error(Loc, "unexpected token in argument list");
2102 }
2103 }
2104 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002105 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2106 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002107 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002108 return Error(Loc, "unexpected token in argument list");
2109 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002110 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002111 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002112}
2113
Jack Carter0b744b32012-10-04 02:29:46 +00002114bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002115 SMLoc Loc = getLexer().getLoc();
2116 Parser.eatToEndOfStatement();
2117 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002118}
2119
2120bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002121 // Line should look like: ".set noat".
2122 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002123 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002124 // eat noat
2125 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002126 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002127 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2128 reportParseError("unexpected token in statement");
2129 return false;
2130 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002131 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002132 return false;
2133}
Jack Carterd0bd6422013-04-18 00:41:53 +00002134
Jack Carter0b744b32012-10-04 02:29:46 +00002135bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002136 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002137 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002138 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002139 getParser().Lex();
2140 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002141 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002142 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002143 return false;
2144 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002145 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002146 if (getLexer().isNot(AsmToken::Dollar)) {
2147 reportParseError("unexpected token in statement");
2148 return false;
2149 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002150 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002151 const AsmToken &Reg = Parser.getTok();
2152 if (Reg.is(AsmToken::Identifier)) {
2153 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2154 } else if (Reg.is(AsmToken::Integer)) {
2155 AtRegNo = Reg.getIntVal();
2156 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002157 reportParseError("unexpected token in statement");
2158 return false;
2159 }
Jack Carter1ac53222013-02-20 23:11:17 +00002160
Jack Carterd0bd6422013-04-18 00:41:53 +00002161 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002162 reportParseError("unexpected token in statement");
2163 return false;
2164 }
2165
2166 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002167 reportParseError("unexpected token in statement");
2168 return false;
2169 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002170 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002171
2172 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2173 reportParseError("unexpected token in statement");
2174 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002175 }
2176 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002177 return false;
2178 } else {
2179 reportParseError("unexpected token in statement");
2180 return false;
2181 }
2182}
2183
2184bool MipsAsmParser::parseSetReorderDirective() {
2185 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002186 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002187 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2188 reportParseError("unexpected token in statement");
2189 return false;
2190 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002191 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002192 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002193 return false;
2194}
2195
2196bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002197 Parser.Lex();
2198 // If this is not the end of the statement, report an error.
2199 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2200 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002201 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002202 }
2203 Options.setNoreorder();
2204 Parser.Lex(); // Consume the EndOfStatement.
2205 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002206}
2207
2208bool MipsAsmParser::parseSetMacroDirective() {
2209 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002210 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002211 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2212 reportParseError("unexpected token in statement");
2213 return false;
2214 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002215 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002216 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002217 return false;
2218}
2219
2220bool MipsAsmParser::parseSetNoMacroDirective() {
2221 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002222 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002223 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2224 reportParseError("`noreorder' must be set before `nomacro'");
2225 return false;
2226 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002227 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002228 reportParseError("`noreorder' must be set before `nomacro'");
2229 return false;
2230 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002231 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002232 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002233 return false;
2234}
Jack Carterd76b2372013-03-21 21:44:16 +00002235
2236bool MipsAsmParser::parseSetAssignment() {
2237 StringRef Name;
2238 const MCExpr *Value;
2239
2240 if (Parser.parseIdentifier(Name))
2241 reportParseError("expected identifier after .set");
2242
2243 if (getLexer().isNot(AsmToken::Comma))
2244 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002245 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002246
Jack Carter02593002013-05-28 22:21:05 +00002247 if (getLexer().is(AsmToken::Dollar)) {
2248 MCSymbol *Symbol;
2249 SMLoc DollarLoc = getLexer().getLoc();
2250 // Consume the dollar sign, and check for a following identifier.
2251 Parser.Lex();
2252 // We have a '$' followed by something, make sure they are adjacent.
2253 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2254 return true;
2255 StringRef Res = StringRef(DollarLoc.getPointer(),
2256 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2257 Symbol = getContext().GetOrCreateSymbol(Res);
2258 Parser.Lex();
2259 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
2260 getContext());
2261 } else if (Parser.parseExpression(Value))
2262 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002263
Jack Carterd0bd6422013-04-18 00:41:53 +00002264 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002265 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002266 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002267 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002268 Sym = getContext().GetOrCreateSymbol(Name);
2269 Sym->setVariableValue(Value);
2270
2271 return false;
2272}
Jack Carterd0bd6422013-04-18 00:41:53 +00002273
Jack Carter0b744b32012-10-04 02:29:46 +00002274bool MipsAsmParser::parseDirectiveSet() {
2275
Jack Carterd0bd6422013-04-18 00:41:53 +00002276 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002277 const AsmToken &Tok = Parser.getTok();
2278
2279 if (Tok.getString() == "noat") {
2280 return parseSetNoAtDirective();
2281 } else if (Tok.getString() == "at") {
2282 return parseSetAtDirective();
2283 } else if (Tok.getString() == "reorder") {
2284 return parseSetReorderDirective();
2285 } else if (Tok.getString() == "noreorder") {
2286 return parseSetNoReorderDirective();
2287 } else if (Tok.getString() == "macro") {
2288 return parseSetMacroDirective();
2289 } else if (Tok.getString() == "nomacro") {
2290 return parseSetNoMacroDirective();
2291 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002292 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002293 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002294 return false;
2295 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002296 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002297 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002298 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002299 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002300 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002301 parseSetAssignment();
2302 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002303 }
Jack Carter07c818d2013-01-25 01:31:34 +00002304
Jack Carter0b744b32012-10-04 02:29:46 +00002305 return true;
2306}
2307
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002308bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2309 MCAsmParser &Parser = getParser();
2310 StringRef Name;
2311 if (Parser.parseIdentifier(Name))
2312 reportParseError("expected identifier");
2313
2314 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2315 if (getLexer().isNot(AsmToken::Comma))
2316 return TokError("unexpected token");
2317 Lex();
2318
2319 int64_t Flags = 0;
2320 if (Parser.parseAbsoluteExpression(Flags))
2321 return TokError("unexpected token");
2322
Rafael Espindolaa17151a2013-10-08 13:08:17 +00002323 getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002324 return false;
2325}
2326
2327bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2328 int64_t Flags = 0;
2329 if (Parser.parseAbsoluteExpression(Flags))
2330 return TokError("unexpected token");
2331
Rafael Espindolaa17151a2013-10-08 13:08:17 +00002332 getTargetStreamer().emitMipsHackELFFlags(Flags);
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002333 return false;
2334}
2335
Jack Carter07c818d2013-01-25 01:31:34 +00002336/// parseDirectiveWord
2337/// ::= .word [ expression (, expression)* ]
2338bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2339 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2340 for (;;) {
2341 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002342 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002343 return true;
2344
2345 getParser().getStreamer().EmitValue(Value, Size);
2346
2347 if (getLexer().is(AsmToken::EndOfStatement))
2348 break;
2349
2350 // FIXME: Improve diagnostic.
2351 if (getLexer().isNot(AsmToken::Comma))
2352 return Error(L, "unexpected token in directive");
2353 Parser.Lex();
2354 }
2355 }
2356
2357 Parser.Lex();
2358 return false;
2359}
2360
Jack Carter0b744b32012-10-04 02:29:46 +00002361bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00002362
Jack Carter07c818d2013-01-25 01:31:34 +00002363 StringRef IDVal = DirectiveID.getString();
2364
Jack Carterd0bd6422013-04-18 00:41:53 +00002365 if (IDVal == ".ent") {
2366 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002367 Parser.Lex();
2368 return false;
2369 }
2370
Jack Carter07c818d2013-01-25 01:31:34 +00002371 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002372 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002373 Parser.Lex();
2374 return false;
2375 }
2376
Jack Carter07c818d2013-01-25 01:31:34 +00002377 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002378 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002379 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002380 return false;
2381 }
2382
Jack Carter07c818d2013-01-25 01:31:34 +00002383 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002384 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002385 }
2386
Jack Carter07c818d2013-01-25 01:31:34 +00002387 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002388 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002389 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002390 return false;
2391 }
2392
Jack Carter07c818d2013-01-25 01:31:34 +00002393 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002394 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002395 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002396 return false;
2397 }
2398
Jack Carter07c818d2013-01-25 01:31:34 +00002399 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002400 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002401 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002402 return false;
2403 }
2404
Jack Carter07c818d2013-01-25 01:31:34 +00002405 if (IDVal == ".word") {
2406 parseDirectiveWord(4, DirectiveID.getLoc());
2407 return false;
2408 }
2409
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002410 if (IDVal == ".mips_hack_stocg")
2411 return parseDirectiveMipsHackStocg();
2412
2413 if (IDVal == ".mips_hack_elf_flags")
2414 return parseDirectiveMipsHackELFFlags();
2415
Rafael Espindola870c4e92012-01-11 03:56:41 +00002416 return true;
2417}
2418
Rafael Espindola870c4e92012-01-11 03:56:41 +00002419extern "C" void LLVMInitializeMipsAsmParser() {
2420 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2421 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2422 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2423 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2424}
Jack Carterb4dbc172012-09-05 23:34:03 +00002425
2426#define GET_REGISTER_MATCHER
2427#define GET_MATCHER_IMPLEMENTATION
2428#include "MipsGenAsmMatcher.inc"