blob: e92d58a879d88aa32d6b5a1fc1ee6062a848c515 [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"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCInst.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "llvm/MC/MCParser/MCAsmLexer.h"
17#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000018#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSubtargetInfo.h"
20#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000021#include "llvm/MC/MCTargetAsmParser.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000022#include "llvm/Support/TargetRegistry.h"
Jack Carter02593002013-05-28 22:21:05 +000023#include "llvm/ADT/APInt.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000024
25using namespace llvm;
26
27namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000028class MipsAssemblerOptions {
29public:
30 MipsAssemblerOptions():
31 aTReg(1), reorder(true), macro(true) {
32 }
Jack Carterb4dbc172012-09-05 23:34:03 +000033
Jack Carter0b744b32012-10-04 02:29:46 +000034 unsigned getATRegNum() {return aTReg;}
35 bool setATReg(unsigned Reg);
36
37 bool isReorder() {return reorder;}
38 void setReorder() {reorder = true;}
39 void setNoreorder() {reorder = false;}
40
41 bool isMacro() {return macro;}
42 void setMacro() {macro = true;}
43 void setNomacro() {macro = false;}
44
45private:
46 unsigned aTReg;
47 bool reorder;
48 bool macro;
49};
50}
51
52namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000053class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000054
Jack Cartera63b16a2012-09-07 00:23:42 +000055 enum FpFormatTy {
56 FP_FORMAT_NONE = -1,
57 FP_FORMAT_S,
58 FP_FORMAT_D,
59 FP_FORMAT_L,
60 FP_FORMAT_W
61 } FpFormat;
62
Jack Carterb4dbc172012-09-05 23:34:03 +000063 MCSubtargetInfo &STI;
64 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000065 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000066 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000067
Akira Hatanaka7605630c2012-08-17 20:16:42 +000068#define GET_ASSEMBLER_HEADER
69#include "MipsGenAsmMatcher.inc"
70
Chad Rosier49963552012-10-13 00:26:04 +000071 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +000072 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000073 MCStreamer &Out, unsigned &ErrorInfo,
74 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000075
76 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
77
Chad Rosierf0e87202012-10-25 20:41:34 +000078 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
79 SMLoc NameLoc,
Akira Hatanaka7605630c2012-08-17 20:16:42 +000080 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000081
82 bool ParseDirective(AsmToken DirectiveID);
83
Jack Carterb4dbc172012-09-05 23:34:03 +000084 MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +000085 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
86 int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000087
88 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000089 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
90
91 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000092 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000093
94 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000095 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000096
97 MipsAsmParser::OperandMatchResultTy
98 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
99
100 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +0000101 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000102
Vladimir Medic233dd512013-06-24 10:05:34 +0000103 MipsAsmParser::OperandMatchResultTy
104 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
105
106 MipsAsmParser::OperandMatchResultTy
107 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
108
109 MipsAsmParser::OperandMatchResultTy
110 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
111
Vladimir Medic643b3982013-07-30 10:12:14 +0000112 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000113 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
114
115 MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +0000116 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
117
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000118 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000119 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000120
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000121 MipsAsmParser::OperandMatchResultTy
122 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
123
124 MipsAsmParser::OperandMatchResultTy
125 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
126
Jack Carterd76b2372013-03-21 21:44:16 +0000127 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000128 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000129
Jack Carterb4dbc172012-09-05 23:34:03 +0000130 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
131 StringRef Mnemonic);
132
Jack Carter873c7242013-01-12 01:03:14 +0000133 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000134
135 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000136 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000137
Jack Carter30a59822012-10-04 04:03:53 +0000138 bool needsExpansion(MCInst &Inst);
139
140 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000141 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000142 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000143 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000144 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
145 SmallVectorImpl<MCInst> &Instructions);
146 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
147 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000148 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
149 SmallVectorImpl<MCInst> &Instructions,
150 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000151 bool reportParseError(StringRef ErrorMsg);
152
Jack Carterb5cf5902013-04-17 00:18:04 +0000153 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000154 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000155
Jack Carterb5cf5902013-04-17 00:18:04 +0000156 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
157
158 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000159 bool parseDirectiveSet();
160
161 bool parseSetAtDirective();
162 bool parseSetNoAtDirective();
163 bool parseSetMacroDirective();
164 bool parseSetNoMacroDirective();
165 bool parseSetReorderDirective();
166 bool parseSetNoReorderDirective();
167
Jack Carterd76b2372013-03-21 21:44:16 +0000168 bool parseSetAssignment();
169
Jack Carter07c818d2013-01-25 01:31:34 +0000170 bool parseDirectiveWord(unsigned Size, SMLoc L);
171
Jack Carterdc1e35d2012-09-06 20:00:02 +0000172 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000173
Jack Carterb4dbc172012-09-05 23:34:03 +0000174 bool isMips64() const {
175 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
176 }
177
Jack Cartera63b16a2012-09-07 00:23:42 +0000178 bool isFP64() const {
179 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
180 }
181
Jack Carter873c7242013-01-12 01:03:14 +0000182 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000183
Jack Carter1ac53222013-02-20 23:11:17 +0000184 int matchCPURegisterName(StringRef Symbol);
185
Jack Carter873c7242013-01-12 01:03:14 +0000186 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000187
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000188 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000189
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000190 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000191
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000192 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000193
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000194 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000195
196 FpFormatTy getFpFormat() {return FpFormat;}
197
Jack Carterd0bd6422013-04-18 00:41:53 +0000198 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000199
Jack Carter1ac53222013-02-20 23:11:17 +0000200 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000201
202 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000204public:
205 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000206 : MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000207 // Initialize the set of available features.
208 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000209 }
210
Jack Carterb4dbc172012-09-05 23:34:03 +0000211 MCAsmParser &getParser() const { return Parser; }
212 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
213
Rafael Espindola870c4e92012-01-11 03:56:41 +0000214};
215}
216
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000217namespace {
218
219/// MipsOperand - Instances of this class represent a parsed Mips machine
220/// instruction.
221class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000222
Jack Carter873c7242013-01-12 01:03:14 +0000223public:
224 enum RegisterKind {
225 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000226 Kind_GPR32,
227 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000228 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000229 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000230 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000231 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000232 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000233 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000234 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000235 Kind_ACC64DSP,
236 Kind_LO32DSP,
237 Kind_HI32DSP
Jack Carter873c7242013-01-12 01:03:14 +0000238 };
239
240private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000241 enum KindTy {
242 k_CondCode,
243 k_CoprocNum,
244 k_Immediate,
245 k_Memory,
246 k_PostIndexRegister,
247 k_Register,
248 k_Token
249 } Kind;
250
251 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000252
Eric Christopher8996c5d2013-03-15 00:42:55 +0000253 struct Token {
254 const char *Data;
255 unsigned Length;
256 };
257
258 struct RegOp {
259 unsigned RegNum;
260 RegisterKind Kind;
261 };
262
263 struct ImmOp {
264 const MCExpr *Val;
265 };
266
267 struct MemOp {
268 unsigned Base;
269 const MCExpr *Off;
270 };
271
Jack Carterb4dbc172012-09-05 23:34:03 +0000272 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000273 struct Token Tok;
274 struct RegOp Reg;
275 struct ImmOp Imm;
276 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000277 };
278
279 SMLoc StartLoc, EndLoc;
280
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000281public:
282 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000283 assert(N == 1 && "Invalid number of operands!");
284 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000285 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000286
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000287 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000288 // Add as immediate when possible. Null MCExpr = 0.
289 if (Expr == 0)
290 Inst.addOperand(MCOperand::CreateImm(0));
291 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
292 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
293 else
294 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000295 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000296
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000297 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000298 assert(N == 1 && "Invalid number of operands!");
299 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000300 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000301 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000302
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000303 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000304 assert(N == 2 && "Invalid number of operands!");
305
306 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
307
308 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000309 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000310 }
311
312 bool isReg() const { return Kind == k_Register; }
313 bool isImm() const { return Kind == k_Immediate; }
314 bool isToken() const { return Kind == k_Token; }
315 bool isMem() const { return Kind == k_Memory; }
316
317 StringRef getToken() const {
318 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000319 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000320 }
321
322 unsigned getReg() const {
323 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000324 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000325 }
326
Jack Carter873c7242013-01-12 01:03:14 +0000327 void setRegKind(RegisterKind RegKind) {
328 assert((Kind == k_Register) && "Invalid access!");
329 Reg.Kind = RegKind;
330 }
331
Jack Carterb4dbc172012-09-05 23:34:03 +0000332 const MCExpr *getImm() const {
333 assert((Kind == k_Immediate) && "Invalid access!");
334 return Imm.Val;
335 }
336
Jack Carterdc1e35d2012-09-06 20:00:02 +0000337 unsigned getMemBase() const {
338 assert((Kind == k_Memory) && "Invalid access!");
339 return Mem.Base;
340 }
341
342 const MCExpr *getMemOff() const {
343 assert((Kind == k_Memory) && "Invalid access!");
344 return Mem.Off;
345 }
346
Jack Carterb4dbc172012-09-05 23:34:03 +0000347 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
348 MipsOperand *Op = new MipsOperand(k_Token);
349 Op->Tok.Data = Str.data();
350 Op->Tok.Length = Str.size();
351 Op->StartLoc = S;
352 Op->EndLoc = S;
353 return Op;
354 }
355
356 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
357 MipsOperand *Op = new MipsOperand(k_Register);
358 Op->Reg.RegNum = RegNum;
359 Op->StartLoc = S;
360 Op->EndLoc = E;
361 return Op;
362 }
363
364 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
365 MipsOperand *Op = new MipsOperand(k_Immediate);
366 Op->Imm.Val = Val;
367 Op->StartLoc = S;
368 Op->EndLoc = E;
369 return Op;
370 }
371
Jack Carterdc1e35d2012-09-06 20:00:02 +0000372 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
373 SMLoc S, SMLoc E) {
374 MipsOperand *Op = new MipsOperand(k_Memory);
375 Op->Mem.Base = Base;
376 Op->Mem.Off = Off;
377 Op->StartLoc = S;
378 Op->EndLoc = E;
379 return Op;
380 }
381
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000382 bool isGPR32Asm() const {
383 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000384 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000385 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000386 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
387 }
388
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000389 bool isGPR64Asm() const {
390 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000391 }
Jack Carter873c7242013-01-12 01:03:14 +0000392
393 bool isHWRegsAsm() const {
394 assert((Kind == k_Register) && "Invalid access!");
395 return Reg.Kind == Kind_HWRegs;
396 }
Jack Carter873c7242013-01-12 01:03:14 +0000397
Jack Carter873c7242013-01-12 01:03:14 +0000398 bool isCCRAsm() const {
399 assert((Kind == k_Register) && "Invalid access!");
400 return Reg.Kind == Kind_CCRRegs;
401 }
402
Vladimir Medic233dd512013-06-24 10:05:34 +0000403 bool isAFGR64Asm() const {
404 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
405 }
406
407 bool isFGR64Asm() const {
408 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
409 }
410
411 bool isFGR32Asm() const {
412 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
413 }
414
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000415 bool isFGRH32Asm() const {
416 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
417 }
418
Vladimir Medic643b3982013-07-30 10:12:14 +0000419 bool isFCCRegsAsm() const {
420 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
421 }
422
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000423 bool isACC64DSPAsm() const {
424 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000425 }
426
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000427 bool isLO32DSPAsm() const {
428 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
429 }
430
431 bool isHI32DSPAsm() const {
432 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
433 }
434
Jack Carterb4dbc172012-09-05 23:34:03 +0000435 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000436 SMLoc getStartLoc() const {
437 return StartLoc;
438 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000439 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000440 SMLoc getEndLoc() const {
441 return EndLoc;
442 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000443
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000444 virtual void print(raw_ostream &OS) const {
445 llvm_unreachable("unimplemented!");
446 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000447}; // class MipsOperand
448} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000449
Jack Carter9e65aa32013-03-22 00:05:30 +0000450namespace llvm {
451extern const MCInstrDesc MipsInsts[];
452}
453static const MCInstrDesc &getInstDesc(unsigned Opcode) {
454 return MipsInsts[Opcode];
455}
456
457bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000458 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000459 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
460 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000461 if (MCID.hasDelaySlot() && Options.isReorder()) {
462 // If this instruction has a delay slot and .set reorder is active,
463 // emit a NOP after it.
464 Instructions.push_back(Inst);
465 MCInst NopInst;
466 NopInst.setOpcode(Mips::SLL);
467 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
468 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
469 NopInst.addOperand(MCOperand::CreateImm(0));
470 Instructions.push_back(NopInst);
471 return false;
472 }
473
Jack Carter9e65aa32013-03-22 00:05:30 +0000474 if (MCID.mayLoad() || MCID.mayStore()) {
475 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000476 // reference or immediate we may have to expand instructions.
477 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000478 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000479 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
480 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000481 MCOperand &Op = Inst.getOperand(i);
482 if (Op.isImm()) {
483 int MemOffset = Op.getImm();
484 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000485 // Offset can't exceed 16bit value.
486 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000487 return false;
488 }
489 } else if (Op.isExpr()) {
490 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000491 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000492 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000493 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000494 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000495 // Expand symbol.
496 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000497 return false;
498 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000499 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000500 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000501 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000502 }
503 }
504 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000505 } // for
506 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000507
508 if (needsExpansion(Inst))
509 expandInstruction(Inst, IDLoc, Instructions);
510 else
511 Instructions.push_back(Inst);
512
513 return false;
514}
515
Jack Carter30a59822012-10-04 04:03:53 +0000516bool MipsAsmParser::needsExpansion(MCInst &Inst) {
517
Jack Carterd0bd6422013-04-18 00:41:53 +0000518 switch (Inst.getOpcode()) {
519 case Mips::LoadImm32Reg:
520 case Mips::LoadAddr32Imm:
521 case Mips::LoadAddr32Reg:
522 return true;
523 default:
524 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000525 }
526}
Jack Carter92995f12012-10-06 00:53:28 +0000527
Jack Carter30a59822012-10-04 04:03:53 +0000528void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000529 SmallVectorImpl<MCInst> &Instructions) {
530 switch (Inst.getOpcode()) {
531 case Mips::LoadImm32Reg:
532 return expandLoadImm(Inst, IDLoc, Instructions);
533 case Mips::LoadAddr32Imm:
534 return expandLoadAddressImm(Inst, IDLoc, Instructions);
535 case Mips::LoadAddr32Reg:
536 return expandLoadAddressReg(Inst, IDLoc, Instructions);
537 }
Jack Carter30a59822012-10-04 04:03:53 +0000538}
Jack Carter92995f12012-10-06 00:53:28 +0000539
Jack Carter30a59822012-10-04 04:03:53 +0000540void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000541 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000542 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000543 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000544 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000545 const MCOperand &RegOp = Inst.getOperand(0);
546 assert(RegOp.isReg() && "expected register operand kind");
547
548 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000549 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000550 if (0 <= ImmValue && ImmValue <= 65535) {
551 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000552 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000553 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000554 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000555 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000556 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000557 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000558 } else if (ImmValue < 0 && ImmValue >= -32768) {
559 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000560 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000561 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000562 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000563 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000564 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000565 Instructions.push_back(tmpInst);
566 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000567 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000568 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000569 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000570 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000571 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
572 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000573 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000574 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000575 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000576 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
577 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
578 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
579 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000580 Instructions.push_back(tmpInst);
581 }
582}
Jack Carter92995f12012-10-06 00:53:28 +0000583
Jack Carter543fdf82012-10-09 23:29:45 +0000584void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000585 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000586 MCInst tmpInst;
587 const MCOperand &ImmOp = Inst.getOperand(2);
588 assert(ImmOp.isImm() && "expected immediate operand kind");
589 const MCOperand &SrcRegOp = Inst.getOperand(1);
590 assert(SrcRegOp.isReg() && "expected register operand kind");
591 const MCOperand &DstRegOp = Inst.getOperand(0);
592 assert(DstRegOp.isReg() && "expected register operand kind");
593 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000594 if (-32768 <= ImmValue && ImmValue <= 65535) {
595 // For -32768 <= j <= 65535.
596 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000597 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000598 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
599 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
600 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
601 Instructions.push_back(tmpInst);
602 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000603 // For any other value of j that is representable as a 32-bit integer.
604 // la d,j(s) => lui d,hi16(j)
605 // ori d,d,lo16(j)
606 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000607 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000608 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
609 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
610 Instructions.push_back(tmpInst);
611 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000612 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000613 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
614 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
615 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
616 Instructions.push_back(tmpInst);
617 tmpInst.clear();
618 tmpInst.setOpcode(Mips::ADDu);
619 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
620 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
621 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
622 Instructions.push_back(tmpInst);
623 }
624}
625
626void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000627 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000628 MCInst tmpInst;
629 const MCOperand &ImmOp = Inst.getOperand(1);
630 assert(ImmOp.isImm() && "expected immediate operand kind");
631 const MCOperand &RegOp = Inst.getOperand(0);
632 assert(RegOp.isReg() && "expected register operand kind");
633 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000634 if (-32768 <= ImmValue && ImmValue <= 65535) {
635 // For -32768 <= j <= 65535.
636 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000637 tmpInst.setOpcode(Mips::ADDiu);
638 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000639 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000640 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
641 Instructions.push_back(tmpInst);
642 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000643 // For any other value of j that is representable as a 32-bit integer.
644 // la d,j => lui d,hi16(j)
645 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000646 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000647 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
648 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
649 Instructions.push_back(tmpInst);
650 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000651 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000652 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
653 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
654 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
655 Instructions.push_back(tmpInst);
656 }
657}
658
Jack Carter9e65aa32013-03-22 00:05:30 +0000659void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000660 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000661 const MCSymbolRefExpr *SR;
662 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000663 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000664 const MCExpr *ExprOffset;
665 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000666 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
667 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000668 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000669 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
670 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000671 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000672 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
673 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000674 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000675 if (isImmOpnd) {
676 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
677 ImmOffset = Inst.getOperand(2).getImm();
678 LoOffset = ImmOffset & 0x0000ffff;
679 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000680 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000681 if (LoOffset & 0x8000)
682 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000683 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000684 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000685 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000686 TempInst.setLoc(IDLoc);
687 // 1st instruction in expansion is LUi. For load instruction we can use
688 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000689 // but for stores we must use $at.
690 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000691 TempInst.setOpcode(Mips::LUi);
692 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
693 if (isImmOpnd)
694 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
695 else {
696 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
697 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000698 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
699 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
700 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000701 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000702 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000703 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000704 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000705 }
706 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000707 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000708 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000709 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000710 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000711 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000712 TempInst.setOpcode(Mips::ADDu);
713 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
714 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
715 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
716 Instructions.push_back(TempInst);
717 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000718 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000719 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000720 TempInst.setOpcode(Inst.getOpcode());
721 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
722 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
723 if (isImmOpnd)
724 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
725 else {
726 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000727 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
728 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
729 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000730 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000731 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000732 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000733 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000734 }
735 }
736 Instructions.push_back(TempInst);
737 TempInst.clear();
738}
739
Rafael Espindola870c4e92012-01-11 03:56:41 +0000740bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000741MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000742 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000743 MCStreamer &Out, unsigned &ErrorInfo,
744 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000745 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000746 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000747 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000748 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000749
750 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000751 default:
752 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000753 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000754 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000755 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000756 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000757 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000758 return false;
759 }
760 case Match_MissingFeature:
761 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
762 return true;
763 case Match_InvalidOperand: {
764 SMLoc ErrorLoc = IDLoc;
765 if (ErrorInfo != ~0U) {
766 if (ErrorInfo >= Operands.size())
767 return Error(IDLoc, "too few operands for instruction");
768
Jack Carterd0bd6422013-04-18 00:41:53 +0000769 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
770 if (ErrorLoc == SMLoc())
771 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000772 }
773
774 return Error(ErrorLoc, "invalid operand for instruction");
775 }
776 case Match_MnemonicFail:
777 return Error(IDLoc, "invalid instruction");
778 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000779 return true;
780}
781
Jack Carter1ac53222013-02-20 23:11:17 +0000782int MipsAsmParser::matchCPURegisterName(StringRef Name) {
783 int CC;
784
785 if (Name == "at")
786 return getATReg();
787
788 CC = StringSwitch<unsigned>(Name)
789 .Case("zero", 0)
790 .Case("a0", 4)
791 .Case("a1", 5)
792 .Case("a2", 6)
793 .Case("a3", 7)
794 .Case("v0", 2)
795 .Case("v1", 3)
796 .Case("s0", 16)
797 .Case("s1", 17)
798 .Case("s2", 18)
799 .Case("s3", 19)
800 .Case("s4", 20)
801 .Case("s5", 21)
802 .Case("s6", 22)
803 .Case("s7", 23)
804 .Case("k0", 26)
805 .Case("k1", 27)
806 .Case("sp", 29)
807 .Case("fp", 30)
808 .Case("gp", 28)
809 .Case("ra", 31)
810 .Case("t0", 8)
811 .Case("t1", 9)
812 .Case("t2", 10)
813 .Case("t3", 11)
814 .Case("t4", 12)
815 .Case("t5", 13)
816 .Case("t6", 14)
817 .Case("t7", 15)
818 .Case("t8", 24)
819 .Case("t9", 25)
820 .Default(-1);
821
Jack Carterd0bd6422013-04-18 00:41:53 +0000822 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000823 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
824 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000825 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000826 CC += 4;
827
828 if (CC == -1 && isMips64())
829 CC = StringSwitch<unsigned>(Name)
830 .Case("a4", 8)
831 .Case("a5", 9)
832 .Case("a6", 10)
833 .Case("a7", 11)
834 .Case("kt0", 26)
835 .Case("kt1", 27)
836 .Case("s8", 30)
837 .Default(-1);
838
839 return CC;
840}
Jack Carterd0bd6422013-04-18 00:41:53 +0000841
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000842int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000843
Jack Cartera63b16a2012-09-07 00:23:42 +0000844 if (Name[0] == 'f') {
845 StringRef NumString = Name.substr(1);
846 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000847 if (NumString.getAsInteger(10, IntVal))
848 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000849 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000850 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000851 return IntVal;
852 }
853 return -1;
854}
Jack Cartera63b16a2012-09-07 00:23:42 +0000855
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000856int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
857
858 if (Name.startswith("fcc")) {
859 StringRef NumString = Name.substr(3);
860 unsigned IntVal;
861 if (NumString.getAsInteger(10, IntVal))
862 return -1; // This is not an integer.
863 if (IntVal > 7) // There are only 8 fcc registers.
864 return -1;
865 return IntVal;
866 }
867 return -1;
868}
869
870int MipsAsmParser::matchACRegisterName(StringRef Name) {
871
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000872 if (Name.startswith("ac")) {
873 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000874 unsigned IntVal;
875 if (NumString.getAsInteger(10, IntVal))
876 return -1; // This is not an integer.
877 if (IntVal > 3) // There are only 3 acc registers.
878 return -1;
879 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000880 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000881 return -1;
882}
Jack Carterd0bd6422013-04-18 00:41:53 +0000883
Vladimir Medic8cd17102013-06-20 11:21:49 +0000884int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
885
Vladimir Medic8cd17102013-06-20 11:21:49 +0000886 int CC;
887 CC = matchCPURegisterName(Name);
888 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000889 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
890 : Mips::GPR32RegClassID);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000891 CC= matchFPURegisterName(Name);
892 //TODO: decide about fpu register class
893 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
894 : Mips::FGR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000895}
896
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000897int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000898
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000899 switch (RegKind) {
900 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
901 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
902 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
903 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000904 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000905 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
906 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
907 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
908 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
909 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
910 default :return -1;
911 }
Jack Cartera63b16a2012-09-07 00:23:42 +0000912
Jack Cartera63b16a2012-09-07 00:23:42 +0000913}
Jack Carterb4dbc172012-09-05 23:34:03 +0000914
Jack Carter0b744b32012-10-04 02:29:46 +0000915bool MipsAssemblerOptions::setATReg(unsigned Reg) {
916 if (Reg > 31)
917 return false;
918
919 aTReg = Reg;
920 return true;
921}
922
Jack Carter1ac53222013-02-20 23:11:17 +0000923int MipsAsmParser::getATReg() {
924 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +0000925}
926
Jack Carterd0bd6422013-04-18 00:41:53 +0000927unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +0000928 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +0000929}
930
Jack Carter873c7242013-01-12 01:03:14 +0000931int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000932 if (RegNum >
933 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +0000934 return -1;
935
Jack Carter873c7242013-01-12 01:03:14 +0000936 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +0000937}
938
Jack Carter873c7242013-01-12 01:03:14 +0000939int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000940 const AsmToken &Tok = Parser.getTok();
941 int RegNum = -1;
942
943 if (Tok.is(AsmToken::Identifier)) {
944 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +0000945 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000946 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +0000947 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000948 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +0000949 return RegNum;
950}
951
Jack Carterd0bd6422013-04-18 00:41:53 +0000952bool MipsAsmParser::tryParseRegisterOperand(
953 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000954
955 SMLoc S = Parser.getTok().getLoc();
956 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +0000957
Jack Carter873c7242013-01-12 01:03:14 +0000958 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000959 if (RegNo == -1)
960 return true;
961
Jack Carter873c7242013-01-12 01:03:14 +0000962 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +0000963 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +0000964 Parser.Lex(); // Eat register token.
965 return false;
966}
967
968bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
969 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +0000970 // Check if the current operand has a custom associated parser, if so, try to
971 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +0000972 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
973 if (ResTy == MatchOperand_Success)
974 return false;
975 // If there wasn't a custom match, try the generic matcher below. Otherwise,
976 // there was a match, but an error occurred, in which case, just return that
977 // the operand parsing failed.
978 if (ResTy == MatchOperand_ParseFail)
979 return true;
980
981 switch (getLexer().getKind()) {
982 default:
983 Error(Parser.getTok().getLoc(), "unexpected token in operand");
984 return true;
985 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000986 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +0000987 SMLoc S = Parser.getTok().getLoc();
988 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +0000989 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +0000990 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000991 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000992 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +0000993 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +0000994 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +0000995 if (getLexer().isNot(AsmToken::Dollar))
996 return true;
997
Jack Carterd0bd6422013-04-18 00:41:53 +0000998 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +0000999 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001000 return true;
1001
1002 if (!getLexer().is(AsmToken::RParen))
1003 return true;
1004
1005 S = Parser.getTok().getLoc();
1006 Operands.push_back(MipsOperand::CreateToken(")", S));
1007 Parser.Lex();
1008 }
1009 return false;
1010 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001011 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001012 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001013 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001014 return true;
1015
Jack Carter873c7242013-01-12 01:03:14 +00001016 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001017
Benjamin Kramerfa530572012-09-07 09:47:42 +00001018 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001019
Jack Carterd0bd6422013-04-18 00:41:53 +00001020 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001021 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001022 getContext());
1023
1024 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1025 return false;
1026 }
1027 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001028 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001029 // we need to assigne the propper RegisterKind.
1030 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1031 return false;
1032 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001033 case AsmToken::LParen:
1034 case AsmToken::Minus:
1035 case AsmToken::Plus:
1036 case AsmToken::Integer:
1037 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001038 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001039 const MCExpr *IdVal;
1040 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001041 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001042 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001043 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001044 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1045 return false;
1046 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001047 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001048 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001049 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001050 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001051 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001052 return true;
1053
Jack Carter873c7242013-01-12 01:03:14 +00001054 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1055
Jack Carterdc1e35d2012-09-06 20:00:02 +00001056 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1057 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001058 } // case AsmToken::Percent
1059 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001060 return true;
1061}
1062
Jack Carterb5cf5902013-04-17 00:18:04 +00001063const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1064 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001065 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001066 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001067 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001068 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001069 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001070 short Val = MCE->getValue();
1071 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001072 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001073 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001074 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001075 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001076 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001077 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001078 if (LoSign)
1079 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001080 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001081 } else {
1082 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001083 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001084 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001085 }
1086
Jack Carterb5cf5902013-04-17 00:18:04 +00001087 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001088 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001089 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001090 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001091 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001092 return Res;
1093 }
1094
1095 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001096 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1097 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001098 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1099 return Res;
1100 }
1101
1102 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001103 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1104 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1105 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001106 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001107 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001108 return Expr;
1109}
1110
1111bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1112
1113 switch (Expr->getKind()) {
1114 case MCExpr::Constant:
1115 return true;
1116 case MCExpr::SymbolRef:
1117 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1118 case MCExpr::Binary:
1119 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1120 if (!isEvaluated(BE->getLHS()))
1121 return false;
1122 return isEvaluated(BE->getRHS());
1123 }
1124 case MCExpr::Unary:
1125 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1126 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001127 return false;
1128 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001129 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001130}
Jack Carterd0bd6422013-04-18 00:41:53 +00001131
Jack Carterb5cf5902013-04-17 00:18:04 +00001132bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001133 Parser.Lex(); // Eat the % token.
1134 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001135 if (Tok.isNot(AsmToken::Identifier))
1136 return true;
1137
1138 std::string Str = Tok.getIdentifier().str();
1139
Jack Carterd0bd6422013-04-18 00:41:53 +00001140 Parser.Lex(); // Eat the identifier.
1141 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001142 const MCExpr *IdVal;
1143 SMLoc EndLoc;
1144
1145 if (getLexer().getKind() == AsmToken::LParen) {
1146 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001147 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001148 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001149 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001150 const AsmToken &nextTok = Parser.getTok();
1151 if (nextTok.isNot(AsmToken::Identifier))
1152 return true;
1153 Str += "(%";
1154 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001155 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001156 if (getLexer().getKind() != AsmToken::LParen)
1157 return true;
1158 } else
1159 break;
1160 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001161 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001162 return true;
1163
1164 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001165 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001166
1167 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001168 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001169
Jack Carterd0bd6422013-04-18 00:41:53 +00001170 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001171 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001172}
1173
Jack Carterb4dbc172012-09-05 23:34:03 +00001174bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1175 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001176 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001177 RegNo = tryParseRegister(isMips64());
1178 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001179 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001180}
1181
Jack Carterb5cf5902013-04-17 00:18:04 +00001182bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001183 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001184 bool Result = true;
1185
1186 while (getLexer().getKind() == AsmToken::LParen)
1187 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001188
Jack Carterd0bd6422013-04-18 00:41:53 +00001189 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001190 default:
1191 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001192 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001193 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001194 case AsmToken::Integer:
1195 case AsmToken::Minus:
1196 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001197 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001198 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001199 else
1200 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001201 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001202 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001203 break;
Jack Carter873c7242013-01-12 01:03:14 +00001204 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001205 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001206 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001207 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001208}
1209
Jack Carterb4dbc172012-09-05 23:34:03 +00001210MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001211 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001212
1213 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001214 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001215 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001216 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001217 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001218 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001219
Jack Carterb5cf5902013-04-17 00:18:04 +00001220 if (getLexer().getKind() == AsmToken::LParen) {
1221 Parser.Lex();
1222 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001223 }
1224
Jack Carterb5cf5902013-04-17 00:18:04 +00001225 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001226 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001227 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001228
Jack Carterd0bd6422013-04-18 00:41:53 +00001229 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001230 if (Tok.isNot(AsmToken::LParen)) {
1231 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1232 if (Mnemonic->getToken() == "la") {
1233 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001234 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001235 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1236 return MatchOperand_Success;
1237 }
1238 if (Tok.is(AsmToken::EndOfStatement)) {
1239 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001240 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001241
Jack Carterd0bd6422013-04-18 00:41:53 +00001242 // Zero register assumed, add a memory operand with ZERO as its base.
1243 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1244 : Mips::ZERO,
1245 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001246 return MatchOperand_Success;
1247 }
1248 Error(Parser.getTok().getLoc(), "'(' expected");
1249 return MatchOperand_ParseFail;
1250 }
1251
Jack Carterd0bd6422013-04-18 00:41:53 +00001252 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001253 }
1254
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001255 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1256 (int) MipsOperand::Kind_GPR32);
1257 if (Res != MatchOperand_Success)
1258 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001259
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001260 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001261 Error(Parser.getTok().getLoc(), "')' expected");
1262 return MatchOperand_ParseFail;
1263 }
1264
Jack Carter873c7242013-01-12 01:03:14 +00001265 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1266
Jack Carterd0bd6422013-04-18 00:41:53 +00001267 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001268
1269 if (IdVal == 0)
1270 IdVal = MCConstantExpr::Create(0, getContext());
1271
Jack Carterd0bd6422013-04-18 00:41:53 +00001272 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001273 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1274 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001275 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001276 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001277 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001278 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1279 int64_t Imm;
1280 if (IdVal->EvaluateAsAbsolute(Imm))
1281 IdVal = MCConstantExpr::Create(Imm, getContext());
1282 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1283 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1284 getContext());
1285 }
1286
Jack Carterdc1e35d2012-09-06 20:00:02 +00001287 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1288 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001289 return MatchOperand_Success;
1290}
1291
Jack Carter873c7242013-01-12 01:03:14 +00001292MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001293MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1294 int RegKind) {
1295 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001296 if (getLexer().getKind() == AsmToken::Identifier
1297 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001298 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001299 return MatchOperand_Success;
1300 return MatchOperand_NoMatch;
1301 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001302 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001303 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001304 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001305 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001306 if (!hasConsumedDollar) {
1307 Parser.Lex(); // Eat the '$'
1308 hasConsumedDollar = true;
1309 }
1310 if (getLexer().getKind() == AsmToken::Identifier) {
1311 int RegNum = -1;
1312 std::string RegName = Parser.getTok().getString().lower();
1313 // Match register by name
1314 switch (RegKind) {
1315 case MipsOperand::Kind_GPR32:
1316 case MipsOperand::Kind_GPR64:
1317 RegNum = matchCPURegisterName(RegName);
1318 break;
1319 case MipsOperand::Kind_AFGR64Regs:
1320 case MipsOperand::Kind_FGR64Regs:
1321 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001322 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001323 RegNum = matchFPURegisterName(RegName);
1324 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1325 RegNum /= 2;
1326 break;
1327 case MipsOperand::Kind_FCCRegs:
1328 RegNum = matchFCCRegisterName(RegName);
1329 break;
1330 case MipsOperand::Kind_ACC64DSP:
1331 RegNum = matchACRegisterName(RegName);
1332 break;
1333 default: break; // No match, value is set to -1.
1334 }
1335 // No match found, return _NoMatch to give a chance to other round.
1336 if (RegNum < 0)
1337 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001338
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001339 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1340 if (RegVal == -1)
1341 return MatchOperand_NoMatch;
1342
1343 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1344 Parser.getTok().getLoc());
1345 Op->setRegKind(Kind);
1346 Operands.push_back(Op);
1347 hasConsumedDollar = false;
1348 Parser.Lex(); // Eat the register name.
1349 if ((RegKind == MipsOperand::Kind_GPR32)
1350 && (getLexer().is(AsmToken::LParen))) {
1351 // Check if it is indexed addressing operand.
1352 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1353 Parser.Lex(); // Eat the parenthesis.
1354 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1355 return MatchOperand_NoMatch;
1356 if (getLexer().isNot(AsmToken::RParen))
1357 return MatchOperand_NoMatch;
1358 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1359 Parser.Lex();
1360 }
1361 return MatchOperand_Success;
1362 } else if (getLexer().getKind() == AsmToken::Integer) {
1363 unsigned RegNum = Parser.getTok().getIntVal();
1364 if (Kind == MipsOperand::Kind_HWRegs) {
1365 if (RegNum != 29)
1366 return MatchOperand_NoMatch;
1367 // Only hwreg 29 is supported, found at index 0.
1368 RegNum = 0;
1369 }
1370 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1371 if (Reg == -1)
1372 return MatchOperand_NoMatch;
1373 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1374 Op->setRegKind(Kind);
1375 Operands.push_back(Op);
1376 hasConsumedDollar = false;
1377 Parser.Lex(); // Eat the register number.
1378 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001379 && (getLexer().is(AsmToken::LParen))) {
1380 // Check if it is indexed addressing operand.
1381 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1382 Parser.Lex(); // Eat the parenthesis.
1383 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1384 return MatchOperand_NoMatch;
1385 if (getLexer().isNot(AsmToken::RParen))
1386 return MatchOperand_NoMatch;
1387 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1388 Parser.Lex();
1389 }
Jack Carter873c7242013-01-12 01:03:14 +00001390 return MatchOperand_Success;
1391 }
1392 return MatchOperand_NoMatch;
1393}
Vladimir Medic64828a12013-07-16 10:07:14 +00001394
Vladimir Medic8cd17102013-06-20 11:21:49 +00001395MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001396MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001397
1398 if (!isMips64())
1399 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001400 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001401}
1402
1403MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001404MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1405 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001406}
Jack Carter873c7242013-01-12 01:03:14 +00001407
Vladimir Medic233dd512013-06-24 10:05:34 +00001408MipsAsmParser::OperandMatchResultTy
1409MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1410
1411 if (isFP64())
1412 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001413 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1414}
1415
1416MipsAsmParser::OperandMatchResultTy
1417MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1418 if (!isFP64())
1419 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001420 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1421}
1422
1423MipsAsmParser::OperandMatchResultTy
1424MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001425 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1426}
1427
Vladimir Medic643b3982013-07-30 10:12:14 +00001428MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001429MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1430 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1431}
1432
1433MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001434MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001435 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001436}
1437
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001438MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001439MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001440 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001441}
1442
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001443MipsAsmParser::OperandMatchResultTy
1444MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1445 // If the first token is not '$' we have an error.
1446 if (Parser.getTok().isNot(AsmToken::Dollar))
1447 return MatchOperand_NoMatch;
1448
1449 SMLoc S = Parser.getTok().getLoc();
1450 Parser.Lex(); // Eat the '$'
1451
1452 const AsmToken &Tok = Parser.getTok(); // Get next token.
1453
1454 if (Tok.isNot(AsmToken::Identifier))
1455 return MatchOperand_NoMatch;
1456
1457 if (!Tok.getIdentifier().startswith("ac"))
1458 return MatchOperand_NoMatch;
1459
1460 StringRef NumString = Tok.getIdentifier().substr(2);
1461
1462 unsigned IntVal;
1463 if (NumString.getAsInteger(10, IntVal))
1464 return MatchOperand_NoMatch;
1465
1466 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1467
1468 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1469 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1470 Operands.push_back(Op);
1471
1472 Parser.Lex(); // Eat the register number.
1473 return MatchOperand_Success;
1474}
1475
1476MipsAsmParser::OperandMatchResultTy
1477MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1478 // If the first token is not '$' we have an error.
1479 if (Parser.getTok().isNot(AsmToken::Dollar))
1480 return MatchOperand_NoMatch;
1481
1482 SMLoc S = Parser.getTok().getLoc();
1483 Parser.Lex(); // Eat the '$'
1484
1485 const AsmToken &Tok = Parser.getTok(); // Get next token.
1486
1487 if (Tok.isNot(AsmToken::Identifier))
1488 return MatchOperand_NoMatch;
1489
1490 if (!Tok.getIdentifier().startswith("ac"))
1491 return MatchOperand_NoMatch;
1492
1493 StringRef NumString = Tok.getIdentifier().substr(2);
1494
1495 unsigned IntVal;
1496 if (NumString.getAsInteger(10, IntVal))
1497 return MatchOperand_NoMatch;
1498
1499 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1500
1501 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1502 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1503 Operands.push_back(Op);
1504
1505 Parser.Lex(); // Eat the register number.
1506 return MatchOperand_Success;
1507}
1508
Jack Carterd0bd6422013-04-18 00:41:53 +00001509bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001510 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001511
1512 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1513 if (Sym) {
1514 SMLoc S = Parser.getTok().getLoc();
1515 const MCExpr *Expr;
1516 if (Sym->isVariable())
1517 Expr = Sym->getVariableValue();
1518 else
1519 return false;
1520 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001521 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001522 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1523 const StringRef DefSymbol = Ref->getSymbol().getName();
1524 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001525 int RegNum = -1;
1526 APInt IntVal(32, -1);
1527 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1528 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001529 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001530 ? Mips::GPR64RegClassID
1531 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001532 else {
1533 // Lookup for the register with the corresponding name.
1534 switch (Kind) {
1535 case MipsOperand::Kind_AFGR64Regs:
1536 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001537 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001538 break;
1539 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001540 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001541 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001542 case MipsOperand::Kind_GPR64:
1543 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001544 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001545 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001546 break;
1547 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001548 if (RegNum > -1)
1549 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001550 }
Jack Carterd76b2372013-03-21 21:44:16 +00001551 if (RegNum > -1) {
1552 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001553 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1554 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001555 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001556 Operands.push_back(op);
1557 return true;
1558 }
1559 }
1560 } else if (Expr->getKind() == MCExpr::Constant) {
1561 Parser.Lex();
1562 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001563 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001564 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001565 Operands.push_back(op);
1566 return true;
1567 }
1568 }
1569 return false;
1570}
Jack Carterd0bd6422013-04-18 00:41:53 +00001571
Jack Carter873c7242013-01-12 01:03:14 +00001572MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001573MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001574 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001575}
1576
1577MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001578MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001579 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001580}
1581
Jack Carterdc1e35d2012-09-06 20:00:02 +00001582MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1583
1584 MCSymbolRefExpr::VariantKind VK
1585 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1586 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1587 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1588 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1589 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1590 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1591 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1592 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1593 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1594 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1595 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1596 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1597 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1598 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1599 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1600 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1601 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1602 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1603 .Default(MCSymbolRefExpr::VK_None);
1604
1605 return VK;
1606}
Jack Cartera63b16a2012-09-07 00:23:42 +00001607
Rafael Espindola870c4e92012-01-11 03:56:41 +00001608bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001609ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001610 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001611 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001612 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001613 Parser.eatToEndOfStatement();
1614 return Error(NameLoc, "Unknown instruction");
1615 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001616 // First operand in MCInst is instruction mnemonic.
1617 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001618
1619 // Read the remaining operands.
1620 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1621 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001622 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001623 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001624 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001625 return Error(Loc, "unexpected token in argument list");
1626 }
1627
Jack Carterd0bd6422013-04-18 00:41:53 +00001628 while (getLexer().is(AsmToken::Comma)) {
1629 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001630 // Parse and remember the operand.
1631 if (ParseOperand(Operands, Name)) {
1632 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001633 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001634 return Error(Loc, "unexpected token in argument list");
1635 }
1636 }
1637 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1639 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001640 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001641 return Error(Loc, "unexpected token in argument list");
1642 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001643 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001644 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001645}
1646
Jack Carter0b744b32012-10-04 02:29:46 +00001647bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001648 SMLoc Loc = getLexer().getLoc();
1649 Parser.eatToEndOfStatement();
1650 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001651}
1652
1653bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001654 // Line should look like: ".set noat".
1655 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001656 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001657 // eat noat
1658 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001659 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001660 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1661 reportParseError("unexpected token in statement");
1662 return false;
1663 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001664 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001665 return false;
1666}
Jack Carterd0bd6422013-04-18 00:41:53 +00001667
Jack Carter0b744b32012-10-04 02:29:46 +00001668bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001669 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001670 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001671 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001672 getParser().Lex();
1673 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001674 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001675 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001676 return false;
1677 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001678 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001679 if (getLexer().isNot(AsmToken::Dollar)) {
1680 reportParseError("unexpected token in statement");
1681 return false;
1682 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001683 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001684 const AsmToken &Reg = Parser.getTok();
1685 if (Reg.is(AsmToken::Identifier)) {
1686 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1687 } else if (Reg.is(AsmToken::Integer)) {
1688 AtRegNo = Reg.getIntVal();
1689 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001690 reportParseError("unexpected token in statement");
1691 return false;
1692 }
Jack Carter1ac53222013-02-20 23:11:17 +00001693
Jack Carterd0bd6422013-04-18 00:41:53 +00001694 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001695 reportParseError("unexpected token in statement");
1696 return false;
1697 }
1698
1699 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001700 reportParseError("unexpected token in statement");
1701 return false;
1702 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001703 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001704
1705 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1706 reportParseError("unexpected token in statement");
1707 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001708 }
1709 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001710 return false;
1711 } else {
1712 reportParseError("unexpected token in statement");
1713 return false;
1714 }
1715}
1716
1717bool MipsAsmParser::parseSetReorderDirective() {
1718 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001719 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001720 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1721 reportParseError("unexpected token in statement");
1722 return false;
1723 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001724 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001725 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001726 return false;
1727}
1728
1729bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001730 Parser.Lex();
1731 // If this is not the end of the statement, report an error.
1732 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1733 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001734 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001735 }
1736 Options.setNoreorder();
1737 Parser.Lex(); // Consume the EndOfStatement.
1738 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001739}
1740
1741bool MipsAsmParser::parseSetMacroDirective() {
1742 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001743 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001744 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1745 reportParseError("unexpected token in statement");
1746 return false;
1747 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001748 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001749 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001750 return false;
1751}
1752
1753bool MipsAsmParser::parseSetNoMacroDirective() {
1754 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001755 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001756 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1757 reportParseError("`noreorder' must be set before `nomacro'");
1758 return false;
1759 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001760 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00001761 reportParseError("`noreorder' must be set before `nomacro'");
1762 return false;
1763 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001764 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001765 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001766 return false;
1767}
Jack Carterd76b2372013-03-21 21:44:16 +00001768
1769bool MipsAsmParser::parseSetAssignment() {
1770 StringRef Name;
1771 const MCExpr *Value;
1772
1773 if (Parser.parseIdentifier(Name))
1774 reportParseError("expected identifier after .set");
1775
1776 if (getLexer().isNot(AsmToken::Comma))
1777 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00001778 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00001779
Jack Carter02593002013-05-28 22:21:05 +00001780 if (getLexer().is(AsmToken::Dollar)) {
1781 MCSymbol *Symbol;
1782 SMLoc DollarLoc = getLexer().getLoc();
1783 // Consume the dollar sign, and check for a following identifier.
1784 Parser.Lex();
1785 // We have a '$' followed by something, make sure they are adjacent.
1786 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1787 return true;
1788 StringRef Res = StringRef(DollarLoc.getPointer(),
1789 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1790 Symbol = getContext().GetOrCreateSymbol(Res);
1791 Parser.Lex();
1792 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1793 getContext());
1794 } else if (Parser.parseExpression(Value))
1795 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00001796
Jack Carterd0bd6422013-04-18 00:41:53 +00001797 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00001798 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00001799 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00001800 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00001801 Sym = getContext().GetOrCreateSymbol(Name);
1802 Sym->setVariableValue(Value);
1803
1804 return false;
1805}
Jack Carterd0bd6422013-04-18 00:41:53 +00001806
Jack Carter0b744b32012-10-04 02:29:46 +00001807bool MipsAsmParser::parseDirectiveSet() {
1808
Jack Carterd0bd6422013-04-18 00:41:53 +00001809 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00001810 const AsmToken &Tok = Parser.getTok();
1811
1812 if (Tok.getString() == "noat") {
1813 return parseSetNoAtDirective();
1814 } else if (Tok.getString() == "at") {
1815 return parseSetAtDirective();
1816 } else if (Tok.getString() == "reorder") {
1817 return parseSetReorderDirective();
1818 } else if (Tok.getString() == "noreorder") {
1819 return parseSetNoReorderDirective();
1820 } else if (Tok.getString() == "macro") {
1821 return parseSetMacroDirective();
1822 } else if (Tok.getString() == "nomacro") {
1823 return parseSetNoMacroDirective();
1824 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001825 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001826 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001827 return false;
1828 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001829 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001830 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001831 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001832 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001833 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00001834 parseSetAssignment();
1835 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001836 }
Jack Carter07c818d2013-01-25 01:31:34 +00001837
Jack Carter0b744b32012-10-04 02:29:46 +00001838 return true;
1839}
1840
Jack Carter07c818d2013-01-25 01:31:34 +00001841/// parseDirectiveWord
1842/// ::= .word [ expression (, expression)* ]
1843bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1844 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1845 for (;;) {
1846 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001847 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00001848 return true;
1849
1850 getParser().getStreamer().EmitValue(Value, Size);
1851
1852 if (getLexer().is(AsmToken::EndOfStatement))
1853 break;
1854
1855 // FIXME: Improve diagnostic.
1856 if (getLexer().isNot(AsmToken::Comma))
1857 return Error(L, "unexpected token in directive");
1858 Parser.Lex();
1859 }
1860 }
1861
1862 Parser.Lex();
1863 return false;
1864}
1865
Jack Carter0b744b32012-10-04 02:29:46 +00001866bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00001867
Jack Carter07c818d2013-01-25 01:31:34 +00001868 StringRef IDVal = DirectiveID.getString();
1869
Jack Carterd0bd6422013-04-18 00:41:53 +00001870 if (IDVal == ".ent") {
1871 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001872 Parser.Lex();
1873 return false;
1874 }
1875
Jack Carter07c818d2013-01-25 01:31:34 +00001876 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001877 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001878 Parser.Lex();
1879 return false;
1880 }
1881
Jack Carter07c818d2013-01-25 01:31:34 +00001882 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001883 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001884 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001885 return false;
1886 }
1887
Jack Carter07c818d2013-01-25 01:31:34 +00001888 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00001889 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00001890 }
1891
Jack Carter07c818d2013-01-25 01:31:34 +00001892 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001893 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001894 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001895 return false;
1896 }
1897
Jack Carter07c818d2013-01-25 01:31:34 +00001898 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001899 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001900 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001901 return false;
1902 }
1903
Jack Carter07c818d2013-01-25 01:31:34 +00001904 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001905 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001906 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001907 return false;
1908 }
1909
Jack Carter07c818d2013-01-25 01:31:34 +00001910 if (IDVal == ".word") {
1911 parseDirectiveWord(4, DirectiveID.getLoc());
1912 return false;
1913 }
1914
Rafael Espindola870c4e92012-01-11 03:56:41 +00001915 return true;
1916}
1917
Rafael Espindola870c4e92012-01-11 03:56:41 +00001918extern "C" void LLVMInitializeMipsAsmParser() {
1919 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1920 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1921 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1922 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1923}
Jack Carterb4dbc172012-09-05 23:34:03 +00001924
1925#define GET_REGISTER_MATCHER
1926#define GET_MATCHER_IMPLEMENTATION
1927#include "MipsGenAsmMatcher.inc"