blob: c9bc29ace9dbf90358ad05d083876c6498d33512 [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
113 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
114
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000115 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000116 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000117
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000118 MipsAsmParser::OperandMatchResultTy
119 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
120
121 MipsAsmParser::OperandMatchResultTy
122 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
123
Jack Carterd76b2372013-03-21 21:44:16 +0000124 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000125 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000126
Jack Carterb4dbc172012-09-05 23:34:03 +0000127 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
128 StringRef Mnemonic);
129
Jack Carter873c7242013-01-12 01:03:14 +0000130 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000131
132 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000133 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000134
Jack Carter30a59822012-10-04 04:03:53 +0000135 bool needsExpansion(MCInst &Inst);
136
137 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000138 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000139 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000140 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000141 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
142 SmallVectorImpl<MCInst> &Instructions);
143 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
144 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000145 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
146 SmallVectorImpl<MCInst> &Instructions,
147 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000148 bool reportParseError(StringRef ErrorMsg);
149
Jack Carterb5cf5902013-04-17 00:18:04 +0000150 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000151 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000152
Jack Carterb5cf5902013-04-17 00:18:04 +0000153 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
154
155 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000156 bool parseDirectiveSet();
157
158 bool parseSetAtDirective();
159 bool parseSetNoAtDirective();
160 bool parseSetMacroDirective();
161 bool parseSetNoMacroDirective();
162 bool parseSetReorderDirective();
163 bool parseSetNoReorderDirective();
164
Jack Carterd76b2372013-03-21 21:44:16 +0000165 bool parseSetAssignment();
166
Jack Carter07c818d2013-01-25 01:31:34 +0000167 bool parseDirectiveWord(unsigned Size, SMLoc L);
168
Jack Carterdc1e35d2012-09-06 20:00:02 +0000169 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000170
Jack Carterb4dbc172012-09-05 23:34:03 +0000171 bool isMips64() const {
172 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
173 }
174
Jack Cartera63b16a2012-09-07 00:23:42 +0000175 bool isFP64() const {
176 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
177 }
178
Jack Carter873c7242013-01-12 01:03:14 +0000179 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000180
Jack Carter1ac53222013-02-20 23:11:17 +0000181 int matchCPURegisterName(StringRef Symbol);
182
Jack Carter873c7242013-01-12 01:03:14 +0000183 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000184
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000185 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000186
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000187 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000188
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000189 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000190
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000191 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000192
193 FpFormatTy getFpFormat() {return FpFormat;}
194
Jack Carterd0bd6422013-04-18 00:41:53 +0000195 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000196
Jack Carter1ac53222013-02-20 23:11:17 +0000197 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000198
199 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000201public:
202 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000203 : MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000204 // Initialize the set of available features.
205 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000206 }
207
Jack Carterb4dbc172012-09-05 23:34:03 +0000208 MCAsmParser &getParser() const { return Parser; }
209 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
210
Rafael Espindola870c4e92012-01-11 03:56:41 +0000211};
212}
213
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000214namespace {
215
216/// MipsOperand - Instances of this class represent a parsed Mips machine
217/// instruction.
218class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000219
Jack Carter873c7242013-01-12 01:03:14 +0000220public:
221 enum RegisterKind {
222 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000223 Kind_GPR32,
224 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000225 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000226 Kind_FGR32Regs,
227 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000228 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000229 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000230 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000231 Kind_ACC64DSP,
232 Kind_LO32DSP,
233 Kind_HI32DSP
Jack Carter873c7242013-01-12 01:03:14 +0000234 };
235
236private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000237 enum KindTy {
238 k_CondCode,
239 k_CoprocNum,
240 k_Immediate,
241 k_Memory,
242 k_PostIndexRegister,
243 k_Register,
244 k_Token
245 } Kind;
246
247 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000248
Eric Christopher8996c5d2013-03-15 00:42:55 +0000249 struct Token {
250 const char *Data;
251 unsigned Length;
252 };
253
254 struct RegOp {
255 unsigned RegNum;
256 RegisterKind Kind;
257 };
258
259 struct ImmOp {
260 const MCExpr *Val;
261 };
262
263 struct MemOp {
264 unsigned Base;
265 const MCExpr *Off;
266 };
267
Jack Carterb4dbc172012-09-05 23:34:03 +0000268 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000269 struct Token Tok;
270 struct RegOp Reg;
271 struct ImmOp Imm;
272 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000273 };
274
275 SMLoc StartLoc, EndLoc;
276
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000277public:
278 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000279 assert(N == 1 && "Invalid number of operands!");
280 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000281 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000282
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000283 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000284 // Add as immediate when possible. Null MCExpr = 0.
285 if (Expr == 0)
286 Inst.addOperand(MCOperand::CreateImm(0));
287 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
288 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
289 else
290 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000291 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000292
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000293 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000294 assert(N == 1 && "Invalid number of operands!");
295 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000296 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000297 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000298
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000299 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000300 assert(N == 2 && "Invalid number of operands!");
301
302 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
303
304 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000305 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000306 }
307
308 bool isReg() const { return Kind == k_Register; }
309 bool isImm() const { return Kind == k_Immediate; }
310 bool isToken() const { return Kind == k_Token; }
311 bool isMem() const { return Kind == k_Memory; }
312
313 StringRef getToken() const {
314 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000315 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000316 }
317
318 unsigned getReg() const {
319 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000320 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000321 }
322
Jack Carter873c7242013-01-12 01:03:14 +0000323 void setRegKind(RegisterKind RegKind) {
324 assert((Kind == k_Register) && "Invalid access!");
325 Reg.Kind = RegKind;
326 }
327
Jack Carterb4dbc172012-09-05 23:34:03 +0000328 const MCExpr *getImm() const {
329 assert((Kind == k_Immediate) && "Invalid access!");
330 return Imm.Val;
331 }
332
Jack Carterdc1e35d2012-09-06 20:00:02 +0000333 unsigned getMemBase() const {
334 assert((Kind == k_Memory) && "Invalid access!");
335 return Mem.Base;
336 }
337
338 const MCExpr *getMemOff() const {
339 assert((Kind == k_Memory) && "Invalid access!");
340 return Mem.Off;
341 }
342
Jack Carterb4dbc172012-09-05 23:34:03 +0000343 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
344 MipsOperand *Op = new MipsOperand(k_Token);
345 Op->Tok.Data = Str.data();
346 Op->Tok.Length = Str.size();
347 Op->StartLoc = S;
348 Op->EndLoc = S;
349 return Op;
350 }
351
352 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
353 MipsOperand *Op = new MipsOperand(k_Register);
354 Op->Reg.RegNum = RegNum;
355 Op->StartLoc = S;
356 Op->EndLoc = E;
357 return Op;
358 }
359
360 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
361 MipsOperand *Op = new MipsOperand(k_Immediate);
362 Op->Imm.Val = Val;
363 Op->StartLoc = S;
364 Op->EndLoc = E;
365 return Op;
366 }
367
Jack Carterdc1e35d2012-09-06 20:00:02 +0000368 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
369 SMLoc S, SMLoc E) {
370 MipsOperand *Op = new MipsOperand(k_Memory);
371 Op->Mem.Base = Base;
372 Op->Mem.Off = Off;
373 Op->StartLoc = S;
374 Op->EndLoc = E;
375 return Op;
376 }
377
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000378 bool isGPR32Asm() const {
379 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000380 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000381 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000382 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
383 }
384
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000385 bool isGPR64Asm() const {
386 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000387 }
Jack Carter873c7242013-01-12 01:03:14 +0000388
389 bool isHWRegsAsm() const {
390 assert((Kind == k_Register) && "Invalid access!");
391 return Reg.Kind == Kind_HWRegs;
392 }
Jack Carter873c7242013-01-12 01:03:14 +0000393
Jack Carter873c7242013-01-12 01:03:14 +0000394 bool isCCRAsm() const {
395 assert((Kind == k_Register) && "Invalid access!");
396 return Reg.Kind == Kind_CCRRegs;
397 }
398
Vladimir Medic233dd512013-06-24 10:05:34 +0000399 bool isAFGR64Asm() const {
400 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
401 }
402
403 bool isFGR64Asm() const {
404 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
405 }
406
407 bool isFGR32Asm() const {
408 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
409 }
410
Vladimir Medic643b3982013-07-30 10:12:14 +0000411 bool isFCCRegsAsm() const {
412 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
413 }
414
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000415 bool isACC64DSPAsm() const {
416 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000417 }
418
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000419 bool isLO32DSPAsm() const {
420 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
421 }
422
423 bool isHI32DSPAsm() const {
424 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
425 }
426
Jack Carterb4dbc172012-09-05 23:34:03 +0000427 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000428 SMLoc getStartLoc() const {
429 return StartLoc;
430 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000431 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000432 SMLoc getEndLoc() const {
433 return EndLoc;
434 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000435
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000436 virtual void print(raw_ostream &OS) const {
437 llvm_unreachable("unimplemented!");
438 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000439}; // class MipsOperand
440} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000441
Jack Carter9e65aa32013-03-22 00:05:30 +0000442namespace llvm {
443extern const MCInstrDesc MipsInsts[];
444}
445static const MCInstrDesc &getInstDesc(unsigned Opcode) {
446 return MipsInsts[Opcode];
447}
448
449bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000450 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000451 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
452 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000453 if (MCID.hasDelaySlot() && Options.isReorder()) {
454 // If this instruction has a delay slot and .set reorder is active,
455 // emit a NOP after it.
456 Instructions.push_back(Inst);
457 MCInst NopInst;
458 NopInst.setOpcode(Mips::SLL);
459 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
460 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
461 NopInst.addOperand(MCOperand::CreateImm(0));
462 Instructions.push_back(NopInst);
463 return false;
464 }
465
Jack Carter9e65aa32013-03-22 00:05:30 +0000466 if (MCID.mayLoad() || MCID.mayStore()) {
467 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000468 // reference or immediate we may have to expand instructions.
469 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000470 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000471 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
472 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000473 MCOperand &Op = Inst.getOperand(i);
474 if (Op.isImm()) {
475 int MemOffset = Op.getImm();
476 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000477 // Offset can't exceed 16bit value.
478 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000479 return false;
480 }
481 } else if (Op.isExpr()) {
482 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000483 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000484 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000485 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000486 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000487 // Expand symbol.
488 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000489 return false;
490 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000491 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000492 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000493 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000494 }
495 }
496 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000497 } // for
498 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000499
500 if (needsExpansion(Inst))
501 expandInstruction(Inst, IDLoc, Instructions);
502 else
503 Instructions.push_back(Inst);
504
505 return false;
506}
507
Jack Carter30a59822012-10-04 04:03:53 +0000508bool MipsAsmParser::needsExpansion(MCInst &Inst) {
509
Jack Carterd0bd6422013-04-18 00:41:53 +0000510 switch (Inst.getOpcode()) {
511 case Mips::LoadImm32Reg:
512 case Mips::LoadAddr32Imm:
513 case Mips::LoadAddr32Reg:
514 return true;
515 default:
516 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000517 }
518}
Jack Carter92995f12012-10-06 00:53:28 +0000519
Jack Carter30a59822012-10-04 04:03:53 +0000520void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000521 SmallVectorImpl<MCInst> &Instructions) {
522 switch (Inst.getOpcode()) {
523 case Mips::LoadImm32Reg:
524 return expandLoadImm(Inst, IDLoc, Instructions);
525 case Mips::LoadAddr32Imm:
526 return expandLoadAddressImm(Inst, IDLoc, Instructions);
527 case Mips::LoadAddr32Reg:
528 return expandLoadAddressReg(Inst, IDLoc, Instructions);
529 }
Jack Carter30a59822012-10-04 04:03:53 +0000530}
Jack Carter92995f12012-10-06 00:53:28 +0000531
Jack Carter30a59822012-10-04 04:03:53 +0000532void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000533 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000534 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000535 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000536 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000537 const MCOperand &RegOp = Inst.getOperand(0);
538 assert(RegOp.isReg() && "expected register operand kind");
539
540 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000541 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000542 if (0 <= ImmValue && ImmValue <= 65535) {
543 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000544 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000545 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000546 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000547 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000548 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000549 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000550 } else if (ImmValue < 0 && ImmValue >= -32768) {
551 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000552 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000553 tmpInst.setOpcode(Mips::ADDiu);
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);
558 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000559 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000560 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000561 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000562 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000563 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
564 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000565 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000566 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000567 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000568 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
569 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
570 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
571 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000572 Instructions.push_back(tmpInst);
573 }
574}
Jack Carter92995f12012-10-06 00:53:28 +0000575
Jack Carter543fdf82012-10-09 23:29:45 +0000576void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000577 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000578 MCInst tmpInst;
579 const MCOperand &ImmOp = Inst.getOperand(2);
580 assert(ImmOp.isImm() && "expected immediate operand kind");
581 const MCOperand &SrcRegOp = Inst.getOperand(1);
582 assert(SrcRegOp.isReg() && "expected register operand kind");
583 const MCOperand &DstRegOp = Inst.getOperand(0);
584 assert(DstRegOp.isReg() && "expected register operand kind");
585 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000586 if (-32768 <= ImmValue && ImmValue <= 65535) {
587 // For -32768 <= j <= 65535.
588 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000589 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000590 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
591 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
592 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
593 Instructions.push_back(tmpInst);
594 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000595 // For any other value of j that is representable as a 32-bit integer.
596 // la d,j(s) => lui d,hi16(j)
597 // ori d,d,lo16(j)
598 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000599 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000600 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
601 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
602 Instructions.push_back(tmpInst);
603 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000604 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000605 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
606 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
607 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
608 Instructions.push_back(tmpInst);
609 tmpInst.clear();
610 tmpInst.setOpcode(Mips::ADDu);
611 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
612 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
613 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
614 Instructions.push_back(tmpInst);
615 }
616}
617
618void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000619 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000620 MCInst tmpInst;
621 const MCOperand &ImmOp = Inst.getOperand(1);
622 assert(ImmOp.isImm() && "expected immediate operand kind");
623 const MCOperand &RegOp = Inst.getOperand(0);
624 assert(RegOp.isReg() && "expected register operand kind");
625 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000626 if (-32768 <= ImmValue && ImmValue <= 65535) {
627 // For -32768 <= j <= 65535.
628 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000629 tmpInst.setOpcode(Mips::ADDiu);
630 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000631 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000632 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
633 Instructions.push_back(tmpInst);
634 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000635 // For any other value of j that is representable as a 32-bit integer.
636 // la d,j => lui d,hi16(j)
637 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000638 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000639 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
640 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
641 Instructions.push_back(tmpInst);
642 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000643 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000644 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
645 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
646 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
647 Instructions.push_back(tmpInst);
648 }
649}
650
Jack Carter9e65aa32013-03-22 00:05:30 +0000651void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000652 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000653 const MCSymbolRefExpr *SR;
654 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000655 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000656 const MCExpr *ExprOffset;
657 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000658 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
659 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000660 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000661 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
662 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000663 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000664 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
665 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000666 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000667 if (isImmOpnd) {
668 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
669 ImmOffset = Inst.getOperand(2).getImm();
670 LoOffset = ImmOffset & 0x0000ffff;
671 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000672 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000673 if (LoOffset & 0x8000)
674 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000675 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000676 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000677 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000678 TempInst.setLoc(IDLoc);
679 // 1st instruction in expansion is LUi. For load instruction we can use
680 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000681 // but for stores we must use $at.
682 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000683 TempInst.setOpcode(Mips::LUi);
684 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
685 if (isImmOpnd)
686 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
687 else {
688 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
689 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000690 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
691 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
692 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000693 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000694 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000695 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000696 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000697 }
698 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000699 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000700 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000701 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000702 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000703 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000704 TempInst.setOpcode(Mips::ADDu);
705 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
706 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
707 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
708 Instructions.push_back(TempInst);
709 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000710 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000711 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000712 TempInst.setOpcode(Inst.getOpcode());
713 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
714 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
715 if (isImmOpnd)
716 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
717 else {
718 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000719 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
720 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
721 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000722 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000723 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000724 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000725 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000726 }
727 }
728 Instructions.push_back(TempInst);
729 TempInst.clear();
730}
731
Rafael Espindola870c4e92012-01-11 03:56:41 +0000732bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000733MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000734 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000735 MCStreamer &Out, unsigned &ErrorInfo,
736 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000737 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000738 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000739 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000740 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000741
742 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000743 default:
744 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000745 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000746 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000747 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000748 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000749 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000750 return false;
751 }
752 case Match_MissingFeature:
753 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
754 return true;
755 case Match_InvalidOperand: {
756 SMLoc ErrorLoc = IDLoc;
757 if (ErrorInfo != ~0U) {
758 if (ErrorInfo >= Operands.size())
759 return Error(IDLoc, "too few operands for instruction");
760
Jack Carterd0bd6422013-04-18 00:41:53 +0000761 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
762 if (ErrorLoc == SMLoc())
763 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000764 }
765
766 return Error(ErrorLoc, "invalid operand for instruction");
767 }
768 case Match_MnemonicFail:
769 return Error(IDLoc, "invalid instruction");
770 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000771 return true;
772}
773
Jack Carter1ac53222013-02-20 23:11:17 +0000774int MipsAsmParser::matchCPURegisterName(StringRef Name) {
775 int CC;
776
777 if (Name == "at")
778 return getATReg();
779
780 CC = StringSwitch<unsigned>(Name)
781 .Case("zero", 0)
782 .Case("a0", 4)
783 .Case("a1", 5)
784 .Case("a2", 6)
785 .Case("a3", 7)
786 .Case("v0", 2)
787 .Case("v1", 3)
788 .Case("s0", 16)
789 .Case("s1", 17)
790 .Case("s2", 18)
791 .Case("s3", 19)
792 .Case("s4", 20)
793 .Case("s5", 21)
794 .Case("s6", 22)
795 .Case("s7", 23)
796 .Case("k0", 26)
797 .Case("k1", 27)
798 .Case("sp", 29)
799 .Case("fp", 30)
800 .Case("gp", 28)
801 .Case("ra", 31)
802 .Case("t0", 8)
803 .Case("t1", 9)
804 .Case("t2", 10)
805 .Case("t3", 11)
806 .Case("t4", 12)
807 .Case("t5", 13)
808 .Case("t6", 14)
809 .Case("t7", 15)
810 .Case("t8", 24)
811 .Case("t9", 25)
812 .Default(-1);
813
Jack Carterd0bd6422013-04-18 00:41:53 +0000814 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000815 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
816 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000817 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000818 CC += 4;
819
820 if (CC == -1 && isMips64())
821 CC = StringSwitch<unsigned>(Name)
822 .Case("a4", 8)
823 .Case("a5", 9)
824 .Case("a6", 10)
825 .Case("a7", 11)
826 .Case("kt0", 26)
827 .Case("kt1", 27)
828 .Case("s8", 30)
829 .Default(-1);
830
831 return CC;
832}
Jack Carterd0bd6422013-04-18 00:41:53 +0000833
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000834int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000835
Jack Cartera63b16a2012-09-07 00:23:42 +0000836 if (Name[0] == 'f') {
837 StringRef NumString = Name.substr(1);
838 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000839 if (NumString.getAsInteger(10, IntVal))
840 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000841 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000842 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000843 return IntVal;
844 }
845 return -1;
846}
Jack Cartera63b16a2012-09-07 00:23:42 +0000847
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000848int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
849
850 if (Name.startswith("fcc")) {
851 StringRef NumString = Name.substr(3);
852 unsigned IntVal;
853 if (NumString.getAsInteger(10, IntVal))
854 return -1; // This is not an integer.
855 if (IntVal > 7) // There are only 8 fcc registers.
856 return -1;
857 return IntVal;
858 }
859 return -1;
860}
861
862int MipsAsmParser::matchACRegisterName(StringRef Name) {
863
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000864 if (Name.startswith("ac")) {
865 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000866 unsigned IntVal;
867 if (NumString.getAsInteger(10, IntVal))
868 return -1; // This is not an integer.
869 if (IntVal > 3) // There are only 3 acc registers.
870 return -1;
871 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000872 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000873 return -1;
874}
Jack Carterd0bd6422013-04-18 00:41:53 +0000875
Vladimir Medic8cd17102013-06-20 11:21:49 +0000876int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
877
Vladimir Medic8cd17102013-06-20 11:21:49 +0000878 int CC;
879 CC = matchCPURegisterName(Name);
880 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000881 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
882 : Mips::GPR32RegClassID);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000883 CC= matchFPURegisterName(Name);
884 //TODO: decide about fpu register class
885 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
886 : Mips::FGR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000887}
888
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000889int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000890
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000891 switch (RegKind) {
892 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
893 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
894 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
895 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
896 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
897 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
898 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
899 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
900 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
901 default :return -1;
902 }
Jack Cartera63b16a2012-09-07 00:23:42 +0000903
Jack Cartera63b16a2012-09-07 00:23:42 +0000904}
Jack Carterb4dbc172012-09-05 23:34:03 +0000905
Jack Carter0b744b32012-10-04 02:29:46 +0000906bool MipsAssemblerOptions::setATReg(unsigned Reg) {
907 if (Reg > 31)
908 return false;
909
910 aTReg = Reg;
911 return true;
912}
913
Jack Carter1ac53222013-02-20 23:11:17 +0000914int MipsAsmParser::getATReg() {
915 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +0000916}
917
Jack Carterd0bd6422013-04-18 00:41:53 +0000918unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +0000919 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +0000920}
921
Jack Carter873c7242013-01-12 01:03:14 +0000922int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000923 if (RegNum >
924 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +0000925 return -1;
926
Jack Carter873c7242013-01-12 01:03:14 +0000927 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +0000928}
929
Jack Carter873c7242013-01-12 01:03:14 +0000930int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000931 const AsmToken &Tok = Parser.getTok();
932 int RegNum = -1;
933
934 if (Tok.is(AsmToken::Identifier)) {
935 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +0000936 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000937 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +0000938 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000939 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +0000940 return RegNum;
941}
942
Jack Carterd0bd6422013-04-18 00:41:53 +0000943bool MipsAsmParser::tryParseRegisterOperand(
944 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000945
946 SMLoc S = Parser.getTok().getLoc();
947 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +0000948
Jack Carter873c7242013-01-12 01:03:14 +0000949 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000950 if (RegNo == -1)
951 return true;
952
Jack Carter873c7242013-01-12 01:03:14 +0000953 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +0000954 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +0000955 Parser.Lex(); // Eat register token.
956 return false;
957}
958
959bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
960 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +0000961 // Check if the current operand has a custom associated parser, if so, try to
962 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +0000963 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
964 if (ResTy == MatchOperand_Success)
965 return false;
966 // If there wasn't a custom match, try the generic matcher below. Otherwise,
967 // there was a match, but an error occurred, in which case, just return that
968 // the operand parsing failed.
969 if (ResTy == MatchOperand_ParseFail)
970 return true;
971
972 switch (getLexer().getKind()) {
973 default:
974 Error(Parser.getTok().getLoc(), "unexpected token in operand");
975 return true;
976 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000977 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +0000978 SMLoc S = Parser.getTok().getLoc();
979 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +0000980 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +0000981 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000982 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000983 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +0000984 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +0000985 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +0000986 if (getLexer().isNot(AsmToken::Dollar))
987 return true;
988
Jack Carterd0bd6422013-04-18 00:41:53 +0000989 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +0000990 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +0000991 return true;
992
993 if (!getLexer().is(AsmToken::RParen))
994 return true;
995
996 S = Parser.getTok().getLoc();
997 Operands.push_back(MipsOperand::CreateToken(")", S));
998 Parser.Lex();
999 }
1000 return false;
1001 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001002 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001003 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001004 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001005 return true;
1006
Jack Carter873c7242013-01-12 01:03:14 +00001007 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001008
Benjamin Kramerfa530572012-09-07 09:47:42 +00001009 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001010
Jack Carterd0bd6422013-04-18 00:41:53 +00001011 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001012 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001013 getContext());
1014
1015 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1016 return false;
1017 }
1018 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001019 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001020 // we need to assigne the propper RegisterKind.
1021 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1022 return false;
1023 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001024 case AsmToken::LParen:
1025 case AsmToken::Minus:
1026 case AsmToken::Plus:
1027 case AsmToken::Integer:
1028 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001029 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001030 const MCExpr *IdVal;
1031 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001032 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001033 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001034 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001035 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1036 return false;
1037 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001038 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001039 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001040 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001041 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001042 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001043 return true;
1044
Jack Carter873c7242013-01-12 01:03:14 +00001045 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1046
Jack Carterdc1e35d2012-09-06 20:00:02 +00001047 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1048 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001049 } // case AsmToken::Percent
1050 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001051 return true;
1052}
1053
Jack Carterb5cf5902013-04-17 00:18:04 +00001054const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1055 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001056 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001057 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001058 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001059 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001060 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001061 short Val = MCE->getValue();
1062 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001063 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001064 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001065 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001066 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001067 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001068 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001069 if (LoSign)
1070 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001071 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001072 } else {
1073 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001074 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001075 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001076 }
1077
Jack Carterb5cf5902013-04-17 00:18:04 +00001078 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001079 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001080 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001081 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001082 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001083 return Res;
1084 }
1085
1086 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001087 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1088 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001089 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1090 return Res;
1091 }
1092
1093 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001094 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1095 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1096 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001097 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001098 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001099 return Expr;
1100}
1101
1102bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1103
1104 switch (Expr->getKind()) {
1105 case MCExpr::Constant:
1106 return true;
1107 case MCExpr::SymbolRef:
1108 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1109 case MCExpr::Binary:
1110 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1111 if (!isEvaluated(BE->getLHS()))
1112 return false;
1113 return isEvaluated(BE->getRHS());
1114 }
1115 case MCExpr::Unary:
1116 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1117 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001118 return false;
1119 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001120 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001121}
Jack Carterd0bd6422013-04-18 00:41:53 +00001122
Jack Carterb5cf5902013-04-17 00:18:04 +00001123bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001124 Parser.Lex(); // Eat the % token.
1125 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001126 if (Tok.isNot(AsmToken::Identifier))
1127 return true;
1128
1129 std::string Str = Tok.getIdentifier().str();
1130
Jack Carterd0bd6422013-04-18 00:41:53 +00001131 Parser.Lex(); // Eat the identifier.
1132 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001133 const MCExpr *IdVal;
1134 SMLoc EndLoc;
1135
1136 if (getLexer().getKind() == AsmToken::LParen) {
1137 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001138 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001139 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001140 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001141 const AsmToken &nextTok = Parser.getTok();
1142 if (nextTok.isNot(AsmToken::Identifier))
1143 return true;
1144 Str += "(%";
1145 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001146 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001147 if (getLexer().getKind() != AsmToken::LParen)
1148 return true;
1149 } else
1150 break;
1151 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001152 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001153 return true;
1154
1155 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001156 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001157
1158 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001159 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001160
Jack Carterd0bd6422013-04-18 00:41:53 +00001161 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001162 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001163}
1164
Jack Carterb4dbc172012-09-05 23:34:03 +00001165bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1166 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001167 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001168 RegNo = tryParseRegister(isMips64());
1169 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001170 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001171}
1172
Jack Carterb5cf5902013-04-17 00:18:04 +00001173bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001174 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001175 bool Result = true;
1176
1177 while (getLexer().getKind() == AsmToken::LParen)
1178 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001179
Jack Carterd0bd6422013-04-18 00:41:53 +00001180 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001181 default:
1182 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001183 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001184 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001185 case AsmToken::Integer:
1186 case AsmToken::Minus:
1187 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001188 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001189 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001190 else
1191 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001192 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001193 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001194 break;
Jack Carter873c7242013-01-12 01:03:14 +00001195 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001196 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001197 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001198 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001199}
1200
Jack Carterb4dbc172012-09-05 23:34:03 +00001201MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001202 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001203
1204 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001205 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001206 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001207 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001208 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001209 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001210
Jack Carterb5cf5902013-04-17 00:18:04 +00001211 if (getLexer().getKind() == AsmToken::LParen) {
1212 Parser.Lex();
1213 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001214 }
1215
Jack Carterb5cf5902013-04-17 00:18:04 +00001216 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001217 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001218 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001219
Jack Carterd0bd6422013-04-18 00:41:53 +00001220 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001221 if (Tok.isNot(AsmToken::LParen)) {
1222 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1223 if (Mnemonic->getToken() == "la") {
1224 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001225 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001226 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1227 return MatchOperand_Success;
1228 }
1229 if (Tok.is(AsmToken::EndOfStatement)) {
1230 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001231 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001232
Jack Carterd0bd6422013-04-18 00:41:53 +00001233 // Zero register assumed, add a memory operand with ZERO as its base.
1234 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1235 : Mips::ZERO,
1236 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001237 return MatchOperand_Success;
1238 }
1239 Error(Parser.getTok().getLoc(), "'(' expected");
1240 return MatchOperand_ParseFail;
1241 }
1242
Jack Carterd0bd6422013-04-18 00:41:53 +00001243 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001244 }
1245
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001246 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1247 (int) MipsOperand::Kind_GPR32);
1248 if (Res != MatchOperand_Success)
1249 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001250
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001251 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001252 Error(Parser.getTok().getLoc(), "')' expected");
1253 return MatchOperand_ParseFail;
1254 }
1255
Jack Carter873c7242013-01-12 01:03:14 +00001256 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1257
Jack Carterd0bd6422013-04-18 00:41:53 +00001258 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001259
1260 if (IdVal == 0)
1261 IdVal = MCConstantExpr::Create(0, getContext());
1262
Jack Carterd0bd6422013-04-18 00:41:53 +00001263 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001264 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1265 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001266 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001267 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001268 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001269 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1270 int64_t Imm;
1271 if (IdVal->EvaluateAsAbsolute(Imm))
1272 IdVal = MCConstantExpr::Create(Imm, getContext());
1273 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1274 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1275 getContext());
1276 }
1277
Jack Carterdc1e35d2012-09-06 20:00:02 +00001278 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1279 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001280 return MatchOperand_Success;
1281}
1282
Jack Carter873c7242013-01-12 01:03:14 +00001283MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001284MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1285 int RegKind) {
1286 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001287 if (getLexer().getKind() == AsmToken::Identifier
1288 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001289 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001290 return MatchOperand_Success;
1291 return MatchOperand_NoMatch;
1292 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001293 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001294 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001295 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001296 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001297 if (!hasConsumedDollar) {
1298 Parser.Lex(); // Eat the '$'
1299 hasConsumedDollar = true;
1300 }
1301 if (getLexer().getKind() == AsmToken::Identifier) {
1302 int RegNum = -1;
1303 std::string RegName = Parser.getTok().getString().lower();
1304 // Match register by name
1305 switch (RegKind) {
1306 case MipsOperand::Kind_GPR32:
1307 case MipsOperand::Kind_GPR64:
1308 RegNum = matchCPURegisterName(RegName);
1309 break;
1310 case MipsOperand::Kind_AFGR64Regs:
1311 case MipsOperand::Kind_FGR64Regs:
1312 case MipsOperand::Kind_FGR32Regs:
1313 RegNum = matchFPURegisterName(RegName);
1314 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1315 RegNum /= 2;
1316 break;
1317 case MipsOperand::Kind_FCCRegs:
1318 RegNum = matchFCCRegisterName(RegName);
1319 break;
1320 case MipsOperand::Kind_ACC64DSP:
1321 RegNum = matchACRegisterName(RegName);
1322 break;
1323 default: break; // No match, value is set to -1.
1324 }
1325 // No match found, return _NoMatch to give a chance to other round.
1326 if (RegNum < 0)
1327 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001328
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001329 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1330 if (RegVal == -1)
1331 return MatchOperand_NoMatch;
1332
1333 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1334 Parser.getTok().getLoc());
1335 Op->setRegKind(Kind);
1336 Operands.push_back(Op);
1337 hasConsumedDollar = false;
1338 Parser.Lex(); // Eat the register name.
1339 if ((RegKind == MipsOperand::Kind_GPR32)
1340 && (getLexer().is(AsmToken::LParen))) {
1341 // Check if it is indexed addressing operand.
1342 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1343 Parser.Lex(); // Eat the parenthesis.
1344 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1345 return MatchOperand_NoMatch;
1346 if (getLexer().isNot(AsmToken::RParen))
1347 return MatchOperand_NoMatch;
1348 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1349 Parser.Lex();
1350 }
1351 return MatchOperand_Success;
1352 } else if (getLexer().getKind() == AsmToken::Integer) {
1353 unsigned RegNum = Parser.getTok().getIntVal();
1354 if (Kind == MipsOperand::Kind_HWRegs) {
1355 if (RegNum != 29)
1356 return MatchOperand_NoMatch;
1357 // Only hwreg 29 is supported, found at index 0.
1358 RegNum = 0;
1359 }
1360 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1361 if (Reg == -1)
1362 return MatchOperand_NoMatch;
1363 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1364 Op->setRegKind(Kind);
1365 Operands.push_back(Op);
1366 hasConsumedDollar = false;
1367 Parser.Lex(); // Eat the register number.
1368 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001369 && (getLexer().is(AsmToken::LParen))) {
1370 // Check if it is indexed addressing operand.
1371 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1372 Parser.Lex(); // Eat the parenthesis.
1373 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1374 return MatchOperand_NoMatch;
1375 if (getLexer().isNot(AsmToken::RParen))
1376 return MatchOperand_NoMatch;
1377 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1378 Parser.Lex();
1379 }
Jack Carter873c7242013-01-12 01:03:14 +00001380 return MatchOperand_Success;
1381 }
1382 return MatchOperand_NoMatch;
1383}
Vladimir Medic64828a12013-07-16 10:07:14 +00001384
Vladimir Medic8cd17102013-06-20 11:21:49 +00001385MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001386MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001387
1388 if (!isMips64())
1389 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001390 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001391}
1392
1393MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001394MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1395 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001396}
Jack Carter873c7242013-01-12 01:03:14 +00001397
Vladimir Medic233dd512013-06-24 10:05:34 +00001398MipsAsmParser::OperandMatchResultTy
1399MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1400
1401 if (isFP64())
1402 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001403 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1404}
1405
1406MipsAsmParser::OperandMatchResultTy
1407MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1408 if (!isFP64())
1409 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001410 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1411}
1412
1413MipsAsmParser::OperandMatchResultTy
1414MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001415 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1416}
1417
Vladimir Medic643b3982013-07-30 10:12:14 +00001418MipsAsmParser::OperandMatchResultTy
1419MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001420 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001421}
1422
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001423MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001424MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001425 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001426}
1427
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001428MipsAsmParser::OperandMatchResultTy
1429MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1430 // If the first token is not '$' we have an error.
1431 if (Parser.getTok().isNot(AsmToken::Dollar))
1432 return MatchOperand_NoMatch;
1433
1434 SMLoc S = Parser.getTok().getLoc();
1435 Parser.Lex(); // Eat the '$'
1436
1437 const AsmToken &Tok = Parser.getTok(); // Get next token.
1438
1439 if (Tok.isNot(AsmToken::Identifier))
1440 return MatchOperand_NoMatch;
1441
1442 if (!Tok.getIdentifier().startswith("ac"))
1443 return MatchOperand_NoMatch;
1444
1445 StringRef NumString = Tok.getIdentifier().substr(2);
1446
1447 unsigned IntVal;
1448 if (NumString.getAsInteger(10, IntVal))
1449 return MatchOperand_NoMatch;
1450
1451 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1452
1453 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1454 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1455 Operands.push_back(Op);
1456
1457 Parser.Lex(); // Eat the register number.
1458 return MatchOperand_Success;
1459}
1460
1461MipsAsmParser::OperandMatchResultTy
1462MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1463 // If the first token is not '$' we have an error.
1464 if (Parser.getTok().isNot(AsmToken::Dollar))
1465 return MatchOperand_NoMatch;
1466
1467 SMLoc S = Parser.getTok().getLoc();
1468 Parser.Lex(); // Eat the '$'
1469
1470 const AsmToken &Tok = Parser.getTok(); // Get next token.
1471
1472 if (Tok.isNot(AsmToken::Identifier))
1473 return MatchOperand_NoMatch;
1474
1475 if (!Tok.getIdentifier().startswith("ac"))
1476 return MatchOperand_NoMatch;
1477
1478 StringRef NumString = Tok.getIdentifier().substr(2);
1479
1480 unsigned IntVal;
1481 if (NumString.getAsInteger(10, IntVal))
1482 return MatchOperand_NoMatch;
1483
1484 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1485
1486 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1487 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1488 Operands.push_back(Op);
1489
1490 Parser.Lex(); // Eat the register number.
1491 return MatchOperand_Success;
1492}
1493
Jack Carterd0bd6422013-04-18 00:41:53 +00001494bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001495 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001496
1497 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1498 if (Sym) {
1499 SMLoc S = Parser.getTok().getLoc();
1500 const MCExpr *Expr;
1501 if (Sym->isVariable())
1502 Expr = Sym->getVariableValue();
1503 else
1504 return false;
1505 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001506 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001507 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1508 const StringRef DefSymbol = Ref->getSymbol().getName();
1509 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001510 int RegNum = -1;
1511 APInt IntVal(32, -1);
1512 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1513 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001514 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001515 ? Mips::GPR64RegClassID
1516 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001517 else {
1518 // Lookup for the register with the corresponding name.
1519 switch (Kind) {
1520 case MipsOperand::Kind_AFGR64Regs:
1521 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001522 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001523 break;
1524 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001525 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001526 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001527 case MipsOperand::Kind_GPR64:
1528 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001529 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001530 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001531 break;
1532 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001533 if (RegNum > -1)
1534 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001535 }
Jack Carterd76b2372013-03-21 21:44:16 +00001536 if (RegNum > -1) {
1537 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001538 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1539 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001540 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001541 Operands.push_back(op);
1542 return true;
1543 }
1544 }
1545 } else if (Expr->getKind() == MCExpr::Constant) {
1546 Parser.Lex();
1547 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001548 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001549 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001550 Operands.push_back(op);
1551 return true;
1552 }
1553 }
1554 return false;
1555}
Jack Carterd0bd6422013-04-18 00:41:53 +00001556
Jack Carter873c7242013-01-12 01:03:14 +00001557MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001558MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001559 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001560}
1561
1562MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001563MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001564 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001565}
1566
Jack Carterdc1e35d2012-09-06 20:00:02 +00001567MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1568
1569 MCSymbolRefExpr::VariantKind VK
1570 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1571 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1572 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1573 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1574 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1575 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1576 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1577 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1578 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1579 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1580 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1581 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1582 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1583 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1584 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1585 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1586 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1587 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1588 .Default(MCSymbolRefExpr::VK_None);
1589
1590 return VK;
1591}
Jack Cartera63b16a2012-09-07 00:23:42 +00001592
Rafael Espindola870c4e92012-01-11 03:56:41 +00001593bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001594ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001595 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001596 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001597 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001598 Parser.eatToEndOfStatement();
1599 return Error(NameLoc, "Unknown instruction");
1600 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001601 // First operand in MCInst is instruction mnemonic.
1602 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001603
1604 // Read the remaining operands.
1605 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1606 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001607 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001608 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001609 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001610 return Error(Loc, "unexpected token in argument list");
1611 }
1612
Jack Carterd0bd6422013-04-18 00:41:53 +00001613 while (getLexer().is(AsmToken::Comma)) {
1614 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001615 // Parse and remember the operand.
1616 if (ParseOperand(Operands, Name)) {
1617 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001618 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001619 return Error(Loc, "unexpected token in argument list");
1620 }
1621 }
1622 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001623 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1624 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001625 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001626 return Error(Loc, "unexpected token in argument list");
1627 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001628 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001629 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001630}
1631
Jack Carter0b744b32012-10-04 02:29:46 +00001632bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001633 SMLoc Loc = getLexer().getLoc();
1634 Parser.eatToEndOfStatement();
1635 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001636}
1637
1638bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001639 // Line should look like: ".set noat".
1640 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001641 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001642 // eat noat
1643 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001644 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001645 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1646 reportParseError("unexpected token in statement");
1647 return false;
1648 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001649 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001650 return false;
1651}
Jack Carterd0bd6422013-04-18 00:41:53 +00001652
Jack Carter0b744b32012-10-04 02:29:46 +00001653bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001654 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001655 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001656 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001657 getParser().Lex();
1658 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001659 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001660 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001661 return false;
1662 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001663 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001664 if (getLexer().isNot(AsmToken::Dollar)) {
1665 reportParseError("unexpected token in statement");
1666 return false;
1667 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001668 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001669 const AsmToken &Reg = Parser.getTok();
1670 if (Reg.is(AsmToken::Identifier)) {
1671 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1672 } else if (Reg.is(AsmToken::Integer)) {
1673 AtRegNo = Reg.getIntVal();
1674 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001675 reportParseError("unexpected token in statement");
1676 return false;
1677 }
Jack Carter1ac53222013-02-20 23:11:17 +00001678
Jack Carterd0bd6422013-04-18 00:41:53 +00001679 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001680 reportParseError("unexpected token in statement");
1681 return false;
1682 }
1683
1684 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001685 reportParseError("unexpected token in statement");
1686 return false;
1687 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001688 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001689
1690 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1691 reportParseError("unexpected token in statement");
1692 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001693 }
1694 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001695 return false;
1696 } else {
1697 reportParseError("unexpected token in statement");
1698 return false;
1699 }
1700}
1701
1702bool MipsAsmParser::parseSetReorderDirective() {
1703 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001704 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001705 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1706 reportParseError("unexpected token in statement");
1707 return false;
1708 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001709 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001710 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001711 return false;
1712}
1713
1714bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001715 Parser.Lex();
1716 // If this is not the end of the statement, report an error.
1717 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1718 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001719 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001720 }
1721 Options.setNoreorder();
1722 Parser.Lex(); // Consume the EndOfStatement.
1723 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001724}
1725
1726bool MipsAsmParser::parseSetMacroDirective() {
1727 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001728 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001729 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1730 reportParseError("unexpected token in statement");
1731 return false;
1732 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001733 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001734 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001735 return false;
1736}
1737
1738bool MipsAsmParser::parseSetNoMacroDirective() {
1739 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001740 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001741 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1742 reportParseError("`noreorder' must be set before `nomacro'");
1743 return false;
1744 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001745 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00001746 reportParseError("`noreorder' must be set before `nomacro'");
1747 return false;
1748 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001749 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001750 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001751 return false;
1752}
Jack Carterd76b2372013-03-21 21:44:16 +00001753
1754bool MipsAsmParser::parseSetAssignment() {
1755 StringRef Name;
1756 const MCExpr *Value;
1757
1758 if (Parser.parseIdentifier(Name))
1759 reportParseError("expected identifier after .set");
1760
1761 if (getLexer().isNot(AsmToken::Comma))
1762 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00001763 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00001764
Jack Carter02593002013-05-28 22:21:05 +00001765 if (getLexer().is(AsmToken::Dollar)) {
1766 MCSymbol *Symbol;
1767 SMLoc DollarLoc = getLexer().getLoc();
1768 // Consume the dollar sign, and check for a following identifier.
1769 Parser.Lex();
1770 // We have a '$' followed by something, make sure they are adjacent.
1771 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1772 return true;
1773 StringRef Res = StringRef(DollarLoc.getPointer(),
1774 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1775 Symbol = getContext().GetOrCreateSymbol(Res);
1776 Parser.Lex();
1777 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1778 getContext());
1779 } else if (Parser.parseExpression(Value))
1780 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00001781
Jack Carterd0bd6422013-04-18 00:41:53 +00001782 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00001783 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00001784 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00001785 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00001786 Sym = getContext().GetOrCreateSymbol(Name);
1787 Sym->setVariableValue(Value);
1788
1789 return false;
1790}
Jack Carterd0bd6422013-04-18 00:41:53 +00001791
Jack Carter0b744b32012-10-04 02:29:46 +00001792bool MipsAsmParser::parseDirectiveSet() {
1793
Jack Carterd0bd6422013-04-18 00:41:53 +00001794 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00001795 const AsmToken &Tok = Parser.getTok();
1796
1797 if (Tok.getString() == "noat") {
1798 return parseSetNoAtDirective();
1799 } else if (Tok.getString() == "at") {
1800 return parseSetAtDirective();
1801 } else if (Tok.getString() == "reorder") {
1802 return parseSetReorderDirective();
1803 } else if (Tok.getString() == "noreorder") {
1804 return parseSetNoReorderDirective();
1805 } else if (Tok.getString() == "macro") {
1806 return parseSetMacroDirective();
1807 } else if (Tok.getString() == "nomacro") {
1808 return parseSetNoMacroDirective();
1809 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001810 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001811 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001812 return false;
1813 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001814 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001815 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001816 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001817 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001818 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00001819 parseSetAssignment();
1820 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001821 }
Jack Carter07c818d2013-01-25 01:31:34 +00001822
Jack Carter0b744b32012-10-04 02:29:46 +00001823 return true;
1824}
1825
Jack Carter07c818d2013-01-25 01:31:34 +00001826/// parseDirectiveWord
1827/// ::= .word [ expression (, expression)* ]
1828bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1829 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1830 for (;;) {
1831 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001832 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00001833 return true;
1834
1835 getParser().getStreamer().EmitValue(Value, Size);
1836
1837 if (getLexer().is(AsmToken::EndOfStatement))
1838 break;
1839
1840 // FIXME: Improve diagnostic.
1841 if (getLexer().isNot(AsmToken::Comma))
1842 return Error(L, "unexpected token in directive");
1843 Parser.Lex();
1844 }
1845 }
1846
1847 Parser.Lex();
1848 return false;
1849}
1850
Jack Carter0b744b32012-10-04 02:29:46 +00001851bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00001852
Jack Carter07c818d2013-01-25 01:31:34 +00001853 StringRef IDVal = DirectiveID.getString();
1854
Jack Carterd0bd6422013-04-18 00:41:53 +00001855 if (IDVal == ".ent") {
1856 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001857 Parser.Lex();
1858 return false;
1859 }
1860
Jack Carter07c818d2013-01-25 01:31:34 +00001861 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001862 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001863 Parser.Lex();
1864 return false;
1865 }
1866
Jack Carter07c818d2013-01-25 01:31:34 +00001867 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001868 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001869 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001870 return false;
1871 }
1872
Jack Carter07c818d2013-01-25 01:31:34 +00001873 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00001874 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00001875 }
1876
Jack Carter07c818d2013-01-25 01:31:34 +00001877 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001878 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001879 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001880 return false;
1881 }
1882
Jack Carter07c818d2013-01-25 01:31:34 +00001883 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001884 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001885 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001886 return false;
1887 }
1888
Jack Carter07c818d2013-01-25 01:31:34 +00001889 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001890 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001891 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001892 return false;
1893 }
1894
Jack Carter07c818d2013-01-25 01:31:34 +00001895 if (IDVal == ".word") {
1896 parseDirectiveWord(4, DirectiveID.getLoc());
1897 return false;
1898 }
1899
Rafael Espindola870c4e92012-01-11 03:56:41 +00001900 return true;
1901}
1902
Rafael Espindola870c4e92012-01-11 03:56:41 +00001903extern "C" void LLVMInitializeMipsAsmParser() {
1904 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1905 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1906 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1907 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1908}
Jack Carterb4dbc172012-09-05 23:34:03 +00001909
1910#define GET_REGISTER_MATCHER
1911#define GET_MATCHER_IMPLEMENTATION
1912#include "MipsGenAsmMatcher.inc"