blob: e547de5121a13c5694baab754eeb5b275359adc0 [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 Carterb4dbc172012-09-05 23:34:03 +000055 MCSubtargetInfo &STI;
56 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000057 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000058 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000059
Akira Hatanaka7605630c2012-08-17 20:16:42 +000060#define GET_ASSEMBLER_HEADER
61#include "MipsGenAsmMatcher.inc"
62
Chad Rosier49963552012-10-13 00:26:04 +000063 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +000064 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000065 MCStreamer &Out, unsigned &ErrorInfo,
66 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000067
68 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
69
Chad Rosierf0e87202012-10-25 20:41:34 +000070 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
71 SMLoc NameLoc,
Akira Hatanaka7605630c2012-08-17 20:16:42 +000072 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000073
74 bool ParseDirective(AsmToken DirectiveID);
75
Jack Carterb4dbc172012-09-05 23:34:03 +000076 MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +000077 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
78 int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000079
80 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000081 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
82
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000083 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
84
85 MipsAsmParser::OperandMatchResultTy
86 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
87
Jack Carter873c7242013-01-12 01:03:14 +000088 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000089 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000090
91 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000092 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000093
94 MipsAsmParser::OperandMatchResultTy
95 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
96
97 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000098 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +000099
Vladimir Medic233dd512013-06-24 10:05:34 +0000100 MipsAsmParser::OperandMatchResultTy
101 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
102
103 MipsAsmParser::OperandMatchResultTy
104 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
105
106 MipsAsmParser::OperandMatchResultTy
107 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
108
Vladimir Medic643b3982013-07-30 10:12:14 +0000109 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000110 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
111
112 MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +0000113 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
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000179 bool isN64() const {
180 return STI.getFeatureBits() & Mips::FeatureN64;
181 }
182
Jack Carter873c7242013-01-12 01:03:14 +0000183 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000184
Jack Carter1ac53222013-02-20 23:11:17 +0000185 int matchCPURegisterName(StringRef Symbol);
186
Jack Carter873c7242013-01-12 01:03:14 +0000187 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000188
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000189 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000190
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000191 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000192
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000193 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000194
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000195 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000196
Jack Carterd0bd6422013-04-18 00:41:53 +0000197 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000198
Jack Carter1ac53222013-02-20 23:11:17 +0000199 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000200
201 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000203public:
204 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000205 : MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000206 // Initialize the set of available features.
207 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000208 }
209
Jack Carterb4dbc172012-09-05 23:34:03 +0000210 MCAsmParser &getParser() const { return Parser; }
211 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
212
Rafael Espindola870c4e92012-01-11 03:56:41 +0000213};
214}
215
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000216namespace {
217
218/// MipsOperand - Instances of this class represent a parsed Mips machine
219/// instruction.
220class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000221
Jack Carter873c7242013-01-12 01:03:14 +0000222public:
223 enum RegisterKind {
224 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000225 Kind_GPR32,
226 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000227 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000228 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000229 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000230 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000231 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000232 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000233 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000234 Kind_ACC64DSP,
235 Kind_LO32DSP,
236 Kind_HI32DSP
Jack Carter873c7242013-01-12 01:03:14 +0000237 };
238
239private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000240 enum KindTy {
241 k_CondCode,
242 k_CoprocNum,
243 k_Immediate,
244 k_Memory,
245 k_PostIndexRegister,
246 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000247 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000248 k_Token
249 } Kind;
250
251 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000252
Eric Christopher8996c5d2013-03-15 00:42:55 +0000253 struct Token {
254 const char *Data;
255 unsigned Length;
256 };
257
258 struct RegOp {
259 unsigned RegNum;
260 RegisterKind Kind;
261 };
262
263 struct ImmOp {
264 const MCExpr *Val;
265 };
266
267 struct MemOp {
268 unsigned Base;
269 const MCExpr *Off;
270 };
271
Jack Carterb4dbc172012-09-05 23:34:03 +0000272 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000273 struct Token Tok;
274 struct RegOp Reg;
275 struct ImmOp Imm;
276 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000277 };
278
279 SMLoc StartLoc, EndLoc;
280
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000281public:
282 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000283 assert(N == 1 && "Invalid number of operands!");
284 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000285 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000286
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000287 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
288 assert(N == 1 && "Invalid number of operands!");
289 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
290 }
291
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000292 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000293 // Add as immediate when possible. Null MCExpr = 0.
294 if (Expr == 0)
295 Inst.addOperand(MCOperand::CreateImm(0));
296 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
297 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
298 else
299 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000300 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000301
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000302 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000303 assert(N == 1 && "Invalid number of operands!");
304 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000305 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000306 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000307
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000308 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000309 assert(N == 2 && "Invalid number of operands!");
310
311 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
312
313 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000314 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000315 }
316
317 bool isReg() const { return Kind == k_Register; }
318 bool isImm() const { return Kind == k_Immediate; }
319 bool isToken() const { return Kind == k_Token; }
320 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000321 bool isPtrReg() const { return Kind == k_PtrReg; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000322
323 StringRef getToken() const {
324 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000325 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000326 }
327
328 unsigned getReg() const {
329 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000330 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000331 }
332
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000333 unsigned getPtrReg() const {
334 assert((Kind == k_PtrReg) && "Invalid access!");
335 return Reg.RegNum;
336 }
337
Jack Carter873c7242013-01-12 01:03:14 +0000338 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000339 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000340 Reg.Kind = RegKind;
341 }
342
Jack Carterb4dbc172012-09-05 23:34:03 +0000343 const MCExpr *getImm() const {
344 assert((Kind == k_Immediate) && "Invalid access!");
345 return Imm.Val;
346 }
347
Jack Carterdc1e35d2012-09-06 20:00:02 +0000348 unsigned getMemBase() const {
349 assert((Kind == k_Memory) && "Invalid access!");
350 return Mem.Base;
351 }
352
353 const MCExpr *getMemOff() const {
354 assert((Kind == k_Memory) && "Invalid access!");
355 return Mem.Off;
356 }
357
Jack Carterb4dbc172012-09-05 23:34:03 +0000358 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
359 MipsOperand *Op = new MipsOperand(k_Token);
360 Op->Tok.Data = Str.data();
361 Op->Tok.Length = Str.size();
362 Op->StartLoc = S;
363 Op->EndLoc = S;
364 return Op;
365 }
366
367 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
368 MipsOperand *Op = new MipsOperand(k_Register);
369 Op->Reg.RegNum = RegNum;
370 Op->StartLoc = S;
371 Op->EndLoc = E;
372 return Op;
373 }
374
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000375 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
376 MipsOperand *Op = new MipsOperand(k_PtrReg);
377 Op->Reg.RegNum = RegNum;
378 Op->StartLoc = S;
379 Op->EndLoc = E;
380 return Op;
381 }
382
Jack Carterb4dbc172012-09-05 23:34:03 +0000383 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
384 MipsOperand *Op = new MipsOperand(k_Immediate);
385 Op->Imm.Val = Val;
386 Op->StartLoc = S;
387 Op->EndLoc = E;
388 return Op;
389 }
390
Jack Carterdc1e35d2012-09-06 20:00:02 +0000391 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
392 SMLoc S, SMLoc E) {
393 MipsOperand *Op = new MipsOperand(k_Memory);
394 Op->Mem.Base = Base;
395 Op->Mem.Off = Off;
396 Op->StartLoc = S;
397 Op->EndLoc = E;
398 return Op;
399 }
400
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000401 bool isGPR32Asm() const {
402 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000403 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000404 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000405 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
406 }
407
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000408 bool isGPR64Asm() const {
409 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000410 }
Jack Carter873c7242013-01-12 01:03:14 +0000411
412 bool isHWRegsAsm() const {
413 assert((Kind == k_Register) && "Invalid access!");
414 return Reg.Kind == Kind_HWRegs;
415 }
Jack Carter873c7242013-01-12 01:03:14 +0000416
Jack Carter873c7242013-01-12 01:03:14 +0000417 bool isCCRAsm() const {
418 assert((Kind == k_Register) && "Invalid access!");
419 return Reg.Kind == Kind_CCRRegs;
420 }
421
Vladimir Medic233dd512013-06-24 10:05:34 +0000422 bool isAFGR64Asm() const {
423 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
424 }
425
426 bool isFGR64Asm() const {
427 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
428 }
429
430 bool isFGR32Asm() const {
431 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
432 }
433
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000434 bool isFGRH32Asm() const {
435 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
436 }
437
Vladimir Medic643b3982013-07-30 10:12:14 +0000438 bool isFCCRegsAsm() const {
439 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
440 }
441
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000442 bool isACC64DSPAsm() const {
443 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000444 }
445
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000446 bool isLO32DSPAsm() const {
447 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
448 }
449
450 bool isHI32DSPAsm() const {
451 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
452 }
453
Jack Carterb4dbc172012-09-05 23:34:03 +0000454 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000455 SMLoc getStartLoc() const {
456 return StartLoc;
457 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000458 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000459 SMLoc getEndLoc() const {
460 return EndLoc;
461 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000462
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000463 virtual void print(raw_ostream &OS) const {
464 llvm_unreachable("unimplemented!");
465 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000466}; // class MipsOperand
467} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000468
Jack Carter9e65aa32013-03-22 00:05:30 +0000469namespace llvm {
470extern const MCInstrDesc MipsInsts[];
471}
472static const MCInstrDesc &getInstDesc(unsigned Opcode) {
473 return MipsInsts[Opcode];
474}
475
476bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000477 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000478 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
479 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000480 if (MCID.hasDelaySlot() && Options.isReorder()) {
481 // If this instruction has a delay slot and .set reorder is active,
482 // emit a NOP after it.
483 Instructions.push_back(Inst);
484 MCInst NopInst;
485 NopInst.setOpcode(Mips::SLL);
486 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
487 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
488 NopInst.addOperand(MCOperand::CreateImm(0));
489 Instructions.push_back(NopInst);
490 return false;
491 }
492
Jack Carter9e65aa32013-03-22 00:05:30 +0000493 if (MCID.mayLoad() || MCID.mayStore()) {
494 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000495 // reference or immediate we may have to expand instructions.
496 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000497 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000498 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
499 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000500 MCOperand &Op = Inst.getOperand(i);
501 if (Op.isImm()) {
502 int MemOffset = Op.getImm();
503 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000504 // Offset can't exceed 16bit value.
505 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000506 return false;
507 }
508 } else if (Op.isExpr()) {
509 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000510 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000511 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000512 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000513 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000514 // Expand symbol.
515 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000516 return false;
517 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000518 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000519 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000520 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000521 }
522 }
523 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000524 } // for
525 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000526
527 if (needsExpansion(Inst))
528 expandInstruction(Inst, IDLoc, Instructions);
529 else
530 Instructions.push_back(Inst);
531
532 return false;
533}
534
Jack Carter30a59822012-10-04 04:03:53 +0000535bool MipsAsmParser::needsExpansion(MCInst &Inst) {
536
Jack Carterd0bd6422013-04-18 00:41:53 +0000537 switch (Inst.getOpcode()) {
538 case Mips::LoadImm32Reg:
539 case Mips::LoadAddr32Imm:
540 case Mips::LoadAddr32Reg:
541 return true;
542 default:
543 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000544 }
545}
Jack Carter92995f12012-10-06 00:53:28 +0000546
Jack Carter30a59822012-10-04 04:03:53 +0000547void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000548 SmallVectorImpl<MCInst> &Instructions) {
549 switch (Inst.getOpcode()) {
550 case Mips::LoadImm32Reg:
551 return expandLoadImm(Inst, IDLoc, Instructions);
552 case Mips::LoadAddr32Imm:
553 return expandLoadAddressImm(Inst, IDLoc, Instructions);
554 case Mips::LoadAddr32Reg:
555 return expandLoadAddressReg(Inst, IDLoc, Instructions);
556 }
Jack Carter30a59822012-10-04 04:03:53 +0000557}
Jack Carter92995f12012-10-06 00:53:28 +0000558
Jack Carter30a59822012-10-04 04:03:53 +0000559void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000560 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000561 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000562 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000563 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000564 const MCOperand &RegOp = Inst.getOperand(0);
565 assert(RegOp.isReg() && "expected register operand kind");
566
567 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000568 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000569 if (0 <= ImmValue && ImmValue <= 65535) {
570 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000571 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000572 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000573 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000574 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000575 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000576 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000577 } else if (ImmValue < 0 && ImmValue >= -32768) {
578 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000579 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000580 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000581 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000582 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000583 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000584 Instructions.push_back(tmpInst);
585 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000586 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000587 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000588 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000589 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000590 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
591 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000592 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000593 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000594 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000595 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
596 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
597 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
598 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000599 Instructions.push_back(tmpInst);
600 }
601}
Jack Carter92995f12012-10-06 00:53:28 +0000602
Jack Carter543fdf82012-10-09 23:29:45 +0000603void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000604 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000605 MCInst tmpInst;
606 const MCOperand &ImmOp = Inst.getOperand(2);
607 assert(ImmOp.isImm() && "expected immediate operand kind");
608 const MCOperand &SrcRegOp = Inst.getOperand(1);
609 assert(SrcRegOp.isReg() && "expected register operand kind");
610 const MCOperand &DstRegOp = Inst.getOperand(0);
611 assert(DstRegOp.isReg() && "expected register operand kind");
612 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000613 if (-32768 <= ImmValue && ImmValue <= 65535) {
614 // For -32768 <= j <= 65535.
615 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000616 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000617 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
618 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
619 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
620 Instructions.push_back(tmpInst);
621 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000622 // For any other value of j that is representable as a 32-bit integer.
623 // la d,j(s) => lui d,hi16(j)
624 // ori d,d,lo16(j)
625 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000626 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000627 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
628 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
629 Instructions.push_back(tmpInst);
630 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000631 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000632 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
633 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
634 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
635 Instructions.push_back(tmpInst);
636 tmpInst.clear();
637 tmpInst.setOpcode(Mips::ADDu);
638 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
639 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
640 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
641 Instructions.push_back(tmpInst);
642 }
643}
644
645void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000646 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000647 MCInst tmpInst;
648 const MCOperand &ImmOp = Inst.getOperand(1);
649 assert(ImmOp.isImm() && "expected immediate operand kind");
650 const MCOperand &RegOp = Inst.getOperand(0);
651 assert(RegOp.isReg() && "expected register operand kind");
652 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000653 if (-32768 <= ImmValue && ImmValue <= 65535) {
654 // For -32768 <= j <= 65535.
655 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000656 tmpInst.setOpcode(Mips::ADDiu);
657 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000658 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000659 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
660 Instructions.push_back(tmpInst);
661 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000662 // For any other value of j that is representable as a 32-bit integer.
663 // la d,j => lui d,hi16(j)
664 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000665 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000666 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
667 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
668 Instructions.push_back(tmpInst);
669 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000670 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000671 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
672 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
673 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
674 Instructions.push_back(tmpInst);
675 }
676}
677
Jack Carter9e65aa32013-03-22 00:05:30 +0000678void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000679 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000680 const MCSymbolRefExpr *SR;
681 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000682 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000683 const MCExpr *ExprOffset;
684 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000685 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
686 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000687 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000688 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
689 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000690 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000691 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
692 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000693 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000694 if (isImmOpnd) {
695 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
696 ImmOffset = Inst.getOperand(2).getImm();
697 LoOffset = ImmOffset & 0x0000ffff;
698 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000699 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000700 if (LoOffset & 0x8000)
701 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000702 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000703 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000704 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000705 TempInst.setLoc(IDLoc);
706 // 1st instruction in expansion is LUi. For load instruction we can use
707 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000708 // but for stores we must use $at.
709 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000710 TempInst.setOpcode(Mips::LUi);
711 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
712 if (isImmOpnd)
713 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
714 else {
715 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
716 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000717 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
718 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
719 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000720 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000721 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000722 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000723 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000724 }
725 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000726 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000727 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000728 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000729 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000730 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000731 TempInst.setOpcode(Mips::ADDu);
732 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
733 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
734 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
735 Instructions.push_back(TempInst);
736 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000737 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000738 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000739 TempInst.setOpcode(Inst.getOpcode());
740 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
741 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
742 if (isImmOpnd)
743 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
744 else {
745 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000746 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
747 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
748 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000749 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000750 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000751 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000752 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000753 }
754 }
755 Instructions.push_back(TempInst);
756 TempInst.clear();
757}
758
Rafael Espindola870c4e92012-01-11 03:56:41 +0000759bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000760MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000761 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000762 MCStreamer &Out, unsigned &ErrorInfo,
763 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000764 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000765 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000766 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000767 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000768
769 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000770 default:
771 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000772 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000773 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000774 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000775 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000776 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000777 return false;
778 }
779 case Match_MissingFeature:
780 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
781 return true;
782 case Match_InvalidOperand: {
783 SMLoc ErrorLoc = IDLoc;
784 if (ErrorInfo != ~0U) {
785 if (ErrorInfo >= Operands.size())
786 return Error(IDLoc, "too few operands for instruction");
787
Jack Carterd0bd6422013-04-18 00:41:53 +0000788 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
789 if (ErrorLoc == SMLoc())
790 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000791 }
792
793 return Error(ErrorLoc, "invalid operand for instruction");
794 }
795 case Match_MnemonicFail:
796 return Error(IDLoc, "invalid instruction");
797 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000798 return true;
799}
800
Jack Carter1ac53222013-02-20 23:11:17 +0000801int MipsAsmParser::matchCPURegisterName(StringRef Name) {
802 int CC;
803
804 if (Name == "at")
805 return getATReg();
806
807 CC = StringSwitch<unsigned>(Name)
808 .Case("zero", 0)
809 .Case("a0", 4)
810 .Case("a1", 5)
811 .Case("a2", 6)
812 .Case("a3", 7)
813 .Case("v0", 2)
814 .Case("v1", 3)
815 .Case("s0", 16)
816 .Case("s1", 17)
817 .Case("s2", 18)
818 .Case("s3", 19)
819 .Case("s4", 20)
820 .Case("s5", 21)
821 .Case("s6", 22)
822 .Case("s7", 23)
823 .Case("k0", 26)
824 .Case("k1", 27)
825 .Case("sp", 29)
826 .Case("fp", 30)
827 .Case("gp", 28)
828 .Case("ra", 31)
829 .Case("t0", 8)
830 .Case("t1", 9)
831 .Case("t2", 10)
832 .Case("t3", 11)
833 .Case("t4", 12)
834 .Case("t5", 13)
835 .Case("t6", 14)
836 .Case("t7", 15)
837 .Case("t8", 24)
838 .Case("t9", 25)
839 .Default(-1);
840
Jack Carterd0bd6422013-04-18 00:41:53 +0000841 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000842 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
843 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000844 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000845 CC += 4;
846
847 if (CC == -1 && isMips64())
848 CC = StringSwitch<unsigned>(Name)
849 .Case("a4", 8)
850 .Case("a5", 9)
851 .Case("a6", 10)
852 .Case("a7", 11)
853 .Case("kt0", 26)
854 .Case("kt1", 27)
855 .Case("s8", 30)
856 .Default(-1);
857
858 return CC;
859}
Jack Carterd0bd6422013-04-18 00:41:53 +0000860
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000861int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000862
Jack Cartera63b16a2012-09-07 00:23:42 +0000863 if (Name[0] == 'f') {
864 StringRef NumString = Name.substr(1);
865 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000866 if (NumString.getAsInteger(10, IntVal))
867 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000868 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000869 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000870 return IntVal;
871 }
872 return -1;
873}
Jack Cartera63b16a2012-09-07 00:23:42 +0000874
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000875int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
876
877 if (Name.startswith("fcc")) {
878 StringRef NumString = Name.substr(3);
879 unsigned IntVal;
880 if (NumString.getAsInteger(10, IntVal))
881 return -1; // This is not an integer.
882 if (IntVal > 7) // There are only 8 fcc registers.
883 return -1;
884 return IntVal;
885 }
886 return -1;
887}
888
889int MipsAsmParser::matchACRegisterName(StringRef Name) {
890
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000891 if (Name.startswith("ac")) {
892 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000893 unsigned IntVal;
894 if (NumString.getAsInteger(10, IntVal))
895 return -1; // This is not an integer.
896 if (IntVal > 3) // There are only 3 acc registers.
897 return -1;
898 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000899 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000900 return -1;
901}
Jack Carterd0bd6422013-04-18 00:41:53 +0000902
Vladimir Medic8cd17102013-06-20 11:21:49 +0000903int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
904
Vladimir Medic8cd17102013-06-20 11:21:49 +0000905 int CC;
906 CC = matchCPURegisterName(Name);
907 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000908 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
909 : Mips::GPR32RegClassID);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000910 CC= matchFPURegisterName(Name);
911 //TODO: decide about fpu register class
912 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
913 : Mips::FGR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000914}
915
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000916int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000917
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000918 switch (RegKind) {
919 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
920 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
921 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
922 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000923 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000924 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
925 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
926 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
927 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
928 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
929 default :return -1;
930 }
Jack Cartera63b16a2012-09-07 00:23:42 +0000931
Jack Cartera63b16a2012-09-07 00:23:42 +0000932}
Jack Carterb4dbc172012-09-05 23:34:03 +0000933
Jack Carter0b744b32012-10-04 02:29:46 +0000934bool MipsAssemblerOptions::setATReg(unsigned Reg) {
935 if (Reg > 31)
936 return false;
937
938 aTReg = Reg;
939 return true;
940}
941
Jack Carter1ac53222013-02-20 23:11:17 +0000942int MipsAsmParser::getATReg() {
943 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +0000944}
945
Jack Carterd0bd6422013-04-18 00:41:53 +0000946unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +0000947 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +0000948}
949
Jack Carter873c7242013-01-12 01:03:14 +0000950int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000951 if (RegNum >
952 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +0000953 return -1;
954
Jack Carter873c7242013-01-12 01:03:14 +0000955 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +0000956}
957
Jack Carter873c7242013-01-12 01:03:14 +0000958int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000959 const AsmToken &Tok = Parser.getTok();
960 int RegNum = -1;
961
962 if (Tok.is(AsmToken::Identifier)) {
963 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +0000964 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000965 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +0000966 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000967 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +0000968 return RegNum;
969}
970
Jack Carterd0bd6422013-04-18 00:41:53 +0000971bool MipsAsmParser::tryParseRegisterOperand(
972 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000973
974 SMLoc S = Parser.getTok().getLoc();
975 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +0000976
Jack Carter873c7242013-01-12 01:03:14 +0000977 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000978 if (RegNo == -1)
979 return true;
980
Jack Carter873c7242013-01-12 01:03:14 +0000981 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +0000982 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +0000983 Parser.Lex(); // Eat register token.
984 return false;
985}
986
987bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
988 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +0000989 // Check if the current operand has a custom associated parser, if so, try to
990 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +0000991 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
992 if (ResTy == MatchOperand_Success)
993 return false;
994 // If there wasn't a custom match, try the generic matcher below. Otherwise,
995 // there was a match, but an error occurred, in which case, just return that
996 // the operand parsing failed.
997 if (ResTy == MatchOperand_ParseFail)
998 return true;
999
1000 switch (getLexer().getKind()) {
1001 default:
1002 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1003 return true;
1004 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001005 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001006 SMLoc S = Parser.getTok().getLoc();
1007 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001008 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001009 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001010 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001011 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001012 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001013 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001014 if (getLexer().isNot(AsmToken::Dollar))
1015 return true;
1016
Jack Carterd0bd6422013-04-18 00:41:53 +00001017 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001018 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001019 return true;
1020
1021 if (!getLexer().is(AsmToken::RParen))
1022 return true;
1023
1024 S = Parser.getTok().getLoc();
1025 Operands.push_back(MipsOperand::CreateToken(")", S));
1026 Parser.Lex();
1027 }
1028 return false;
1029 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001030 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001031 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001032 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001033 return true;
1034
Jack Carter873c7242013-01-12 01:03:14 +00001035 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001036
Benjamin Kramerfa530572012-09-07 09:47:42 +00001037 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001038
Jack Carterd0bd6422013-04-18 00:41:53 +00001039 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001040 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001041 getContext());
1042
1043 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1044 return false;
1045 }
1046 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001047 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001048 // we need to assigne the propper RegisterKind.
1049 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1050 return false;
1051 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001052 case AsmToken::LParen:
1053 case AsmToken::Minus:
1054 case AsmToken::Plus:
1055 case AsmToken::Integer:
1056 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001057 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001058 const MCExpr *IdVal;
1059 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001060 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001061 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001062 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001063 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1064 return false;
1065 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001066 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001067 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001068 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001069 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001070 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001071 return true;
1072
Jack Carter873c7242013-01-12 01:03:14 +00001073 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1074
Jack Carterdc1e35d2012-09-06 20:00:02 +00001075 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1076 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001077 } // case AsmToken::Percent
1078 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001079 return true;
1080}
1081
Jack Carterb5cf5902013-04-17 00:18:04 +00001082const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1083 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001084 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001085 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001086 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001087 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001088 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001089 short Val = MCE->getValue();
1090 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001091 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001092 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001093 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001094 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001095 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001096 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001097 if (LoSign)
1098 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001099 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001100 } else {
1101 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001102 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001103 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001104 }
1105
Jack Carterb5cf5902013-04-17 00:18:04 +00001106 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001107 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001108 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001109 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001110 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001111 return Res;
1112 }
1113
1114 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001115 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1116 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001117 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1118 return Res;
1119 }
1120
1121 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001122 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1123 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1124 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001125 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001126 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001127 return Expr;
1128}
1129
1130bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1131
1132 switch (Expr->getKind()) {
1133 case MCExpr::Constant:
1134 return true;
1135 case MCExpr::SymbolRef:
1136 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1137 case MCExpr::Binary:
1138 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1139 if (!isEvaluated(BE->getLHS()))
1140 return false;
1141 return isEvaluated(BE->getRHS());
1142 }
1143 case MCExpr::Unary:
1144 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1145 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001146 return false;
1147 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001148 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001149}
Jack Carterd0bd6422013-04-18 00:41:53 +00001150
Jack Carterb5cf5902013-04-17 00:18:04 +00001151bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001152 Parser.Lex(); // Eat the % token.
1153 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001154 if (Tok.isNot(AsmToken::Identifier))
1155 return true;
1156
1157 std::string Str = Tok.getIdentifier().str();
1158
Jack Carterd0bd6422013-04-18 00:41:53 +00001159 Parser.Lex(); // Eat the identifier.
1160 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001161 const MCExpr *IdVal;
1162 SMLoc EndLoc;
1163
1164 if (getLexer().getKind() == AsmToken::LParen) {
1165 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001166 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001167 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001168 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001169 const AsmToken &nextTok = Parser.getTok();
1170 if (nextTok.isNot(AsmToken::Identifier))
1171 return true;
1172 Str += "(%";
1173 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001174 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001175 if (getLexer().getKind() != AsmToken::LParen)
1176 return true;
1177 } else
1178 break;
1179 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001180 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001181 return true;
1182
1183 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001184 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001185
1186 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001187 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001188
Jack Carterd0bd6422013-04-18 00:41:53 +00001189 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001190 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001191}
1192
Jack Carterb4dbc172012-09-05 23:34:03 +00001193bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1194 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001195 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001196 RegNo = tryParseRegister(isMips64());
1197 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001198 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001199}
1200
Jack Carterb5cf5902013-04-17 00:18:04 +00001201bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001202 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001203 bool Result = true;
1204
1205 while (getLexer().getKind() == AsmToken::LParen)
1206 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001207
Jack Carterd0bd6422013-04-18 00:41:53 +00001208 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001209 default:
1210 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001211 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001212 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001213 case AsmToken::Integer:
1214 case AsmToken::Minus:
1215 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001216 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001217 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001218 else
1219 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001220 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001221 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001222 break;
Jack Carter873c7242013-01-12 01:03:14 +00001223 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001224 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001225 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001226 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001227}
1228
Jack Carterb4dbc172012-09-05 23:34:03 +00001229MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001230 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001231
1232 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001233 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001234 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001235 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001236 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001237 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001238
Jack Carterb5cf5902013-04-17 00:18:04 +00001239 if (getLexer().getKind() == AsmToken::LParen) {
1240 Parser.Lex();
1241 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001242 }
1243
Jack Carterb5cf5902013-04-17 00:18:04 +00001244 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001245 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001246 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001247
Jack Carterd0bd6422013-04-18 00:41:53 +00001248 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001249 if (Tok.isNot(AsmToken::LParen)) {
1250 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1251 if (Mnemonic->getToken() == "la") {
1252 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001253 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001254 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1255 return MatchOperand_Success;
1256 }
1257 if (Tok.is(AsmToken::EndOfStatement)) {
1258 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001259 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001260
Jack Carterd0bd6422013-04-18 00:41:53 +00001261 // Zero register assumed, add a memory operand with ZERO as its base.
1262 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1263 : Mips::ZERO,
1264 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001265 return MatchOperand_Success;
1266 }
1267 Error(Parser.getTok().getLoc(), "'(' expected");
1268 return MatchOperand_ParseFail;
1269 }
1270
Jack Carterd0bd6422013-04-18 00:41:53 +00001271 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001272 }
1273
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001274 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1275 (int) MipsOperand::Kind_GPR32);
1276 if (Res != MatchOperand_Success)
1277 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001278
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001279 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001280 Error(Parser.getTok().getLoc(), "')' expected");
1281 return MatchOperand_ParseFail;
1282 }
1283
Jack Carter873c7242013-01-12 01:03:14 +00001284 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1285
Jack Carterd0bd6422013-04-18 00:41:53 +00001286 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001287
1288 if (IdVal == 0)
1289 IdVal = MCConstantExpr::Create(0, getContext());
1290
Jack Carterd0bd6422013-04-18 00:41:53 +00001291 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001292 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1293 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001294 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001295 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001296 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001297 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1298 int64_t Imm;
1299 if (IdVal->EvaluateAsAbsolute(Imm))
1300 IdVal = MCConstantExpr::Create(Imm, getContext());
1301 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1302 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1303 getContext());
1304 }
1305
Jack Carterdc1e35d2012-09-06 20:00:02 +00001306 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1307 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001308 return MatchOperand_Success;
1309}
1310
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001311bool
1312MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1313 int RegKind) {
1314 // If the first token is not '$' we have an error.
1315 if (Parser.getTok().isNot(AsmToken::Dollar))
1316 return false;
1317
1318 SMLoc S = Parser.getTok().getLoc();
1319 Parser.Lex();
1320 AsmToken::TokenKind TkKind = getLexer().getKind();
1321 int Reg;
1322
1323 if (TkKind == AsmToken::Integer) {
1324 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1325 regKindToRegClass(RegKind));
1326 if (Reg == -1)
1327 return false;
1328 } else if (TkKind == AsmToken::Identifier) {
1329 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1330 return false;
1331 Reg = getReg(regKindToRegClass(RegKind), Reg);
1332 } else {
1333 return false;
1334 }
1335
1336 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1337 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1338 Operands.push_back(Op);
1339 Parser.Lex();
1340 return true;
1341}
1342
1343MipsAsmParser::OperandMatchResultTy
1344MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1345 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1346 MipsOperand::Kind_GPR32;
1347
1348 // Parse index register.
1349 if (!parsePtrReg(Operands, RegKind))
1350 return MatchOperand_NoMatch;
1351
1352 // Parse '('.
1353 if (Parser.getTok().isNot(AsmToken::LParen))
1354 return MatchOperand_NoMatch;
1355
1356 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1357 Parser.Lex();
1358
1359 // Parse base register.
1360 if (!parsePtrReg(Operands, RegKind))
1361 return MatchOperand_NoMatch;
1362
1363 // Parse ')'.
1364 if (Parser.getTok().isNot(AsmToken::RParen))
1365 return MatchOperand_NoMatch;
1366
1367 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1368 Parser.Lex();
1369
1370 return MatchOperand_Success;
1371}
1372
Jack Carter873c7242013-01-12 01:03:14 +00001373MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001374MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1375 int RegKind) {
1376 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001377 if (getLexer().getKind() == AsmToken::Identifier
1378 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001379 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001380 return MatchOperand_Success;
1381 return MatchOperand_NoMatch;
1382 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001383 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001384 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001385 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001386 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001387 if (!hasConsumedDollar) {
1388 Parser.Lex(); // Eat the '$'
1389 hasConsumedDollar = true;
1390 }
1391 if (getLexer().getKind() == AsmToken::Identifier) {
1392 int RegNum = -1;
1393 std::string RegName = Parser.getTok().getString().lower();
1394 // Match register by name
1395 switch (RegKind) {
1396 case MipsOperand::Kind_GPR32:
1397 case MipsOperand::Kind_GPR64:
1398 RegNum = matchCPURegisterName(RegName);
1399 break;
1400 case MipsOperand::Kind_AFGR64Regs:
1401 case MipsOperand::Kind_FGR64Regs:
1402 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001403 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001404 RegNum = matchFPURegisterName(RegName);
1405 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1406 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001407 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1408 && !isFP64())
1409 if (RegNum != -1 && RegNum %2 != 0)
1410 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001411 break;
1412 case MipsOperand::Kind_FCCRegs:
1413 RegNum = matchFCCRegisterName(RegName);
1414 break;
1415 case MipsOperand::Kind_ACC64DSP:
1416 RegNum = matchACRegisterName(RegName);
1417 break;
1418 default: break; // No match, value is set to -1.
1419 }
1420 // No match found, return _NoMatch to give a chance to other round.
1421 if (RegNum < 0)
1422 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001423
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001424 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1425 if (RegVal == -1)
1426 return MatchOperand_NoMatch;
1427
1428 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1429 Parser.getTok().getLoc());
1430 Op->setRegKind(Kind);
1431 Operands.push_back(Op);
1432 hasConsumedDollar = false;
1433 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001434 return MatchOperand_Success;
1435 } else if (getLexer().getKind() == AsmToken::Integer) {
1436 unsigned RegNum = Parser.getTok().getIntVal();
1437 if (Kind == MipsOperand::Kind_HWRegs) {
1438 if (RegNum != 29)
1439 return MatchOperand_NoMatch;
1440 // Only hwreg 29 is supported, found at index 0.
1441 RegNum = 0;
1442 }
1443 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1444 if (Reg == -1)
1445 return MatchOperand_NoMatch;
1446 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1447 Op->setRegKind(Kind);
1448 Operands.push_back(Op);
1449 hasConsumedDollar = false;
1450 Parser.Lex(); // Eat the register number.
1451 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001452 && (getLexer().is(AsmToken::LParen))) {
1453 // Check if it is indexed addressing operand.
1454 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1455 Parser.Lex(); // Eat the parenthesis.
1456 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1457 return MatchOperand_NoMatch;
1458 if (getLexer().isNot(AsmToken::RParen))
1459 return MatchOperand_NoMatch;
1460 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1461 Parser.Lex();
1462 }
Jack Carter873c7242013-01-12 01:03:14 +00001463 return MatchOperand_Success;
1464 }
1465 return MatchOperand_NoMatch;
1466}
Vladimir Medic64828a12013-07-16 10:07:14 +00001467
Vladimir Medic8cd17102013-06-20 11:21:49 +00001468MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001469MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001470
1471 if (!isMips64())
1472 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001473 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001474}
1475
1476MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001477MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1478 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001479}
Jack Carter873c7242013-01-12 01:03:14 +00001480
Vladimir Medic233dd512013-06-24 10:05:34 +00001481MipsAsmParser::OperandMatchResultTy
1482MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1483
1484 if (isFP64())
1485 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001486 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1487}
1488
1489MipsAsmParser::OperandMatchResultTy
1490MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1491 if (!isFP64())
1492 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001493 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1494}
1495
1496MipsAsmParser::OperandMatchResultTy
1497MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001498 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1499}
1500
Vladimir Medic643b3982013-07-30 10:12:14 +00001501MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001502MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1503 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1504}
1505
1506MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001507MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001508 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001509}
1510
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001511MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001512MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001513 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001514}
1515
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001516MipsAsmParser::OperandMatchResultTy
1517MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1518 // If the first token is not '$' we have an error.
1519 if (Parser.getTok().isNot(AsmToken::Dollar))
1520 return MatchOperand_NoMatch;
1521
1522 SMLoc S = Parser.getTok().getLoc();
1523 Parser.Lex(); // Eat the '$'
1524
1525 const AsmToken &Tok = Parser.getTok(); // Get next token.
1526
1527 if (Tok.isNot(AsmToken::Identifier))
1528 return MatchOperand_NoMatch;
1529
1530 if (!Tok.getIdentifier().startswith("ac"))
1531 return MatchOperand_NoMatch;
1532
1533 StringRef NumString = Tok.getIdentifier().substr(2);
1534
1535 unsigned IntVal;
1536 if (NumString.getAsInteger(10, IntVal))
1537 return MatchOperand_NoMatch;
1538
1539 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1540
1541 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1542 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1543 Operands.push_back(Op);
1544
1545 Parser.Lex(); // Eat the register number.
1546 return MatchOperand_Success;
1547}
1548
1549MipsAsmParser::OperandMatchResultTy
1550MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1551 // If the first token is not '$' we have an error.
1552 if (Parser.getTok().isNot(AsmToken::Dollar))
1553 return MatchOperand_NoMatch;
1554
1555 SMLoc S = Parser.getTok().getLoc();
1556 Parser.Lex(); // Eat the '$'
1557
1558 const AsmToken &Tok = Parser.getTok(); // Get next token.
1559
1560 if (Tok.isNot(AsmToken::Identifier))
1561 return MatchOperand_NoMatch;
1562
1563 if (!Tok.getIdentifier().startswith("ac"))
1564 return MatchOperand_NoMatch;
1565
1566 StringRef NumString = Tok.getIdentifier().substr(2);
1567
1568 unsigned IntVal;
1569 if (NumString.getAsInteger(10, IntVal))
1570 return MatchOperand_NoMatch;
1571
1572 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1573
1574 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1575 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1576 Operands.push_back(Op);
1577
1578 Parser.Lex(); // Eat the register number.
1579 return MatchOperand_Success;
1580}
1581
Jack Carterd0bd6422013-04-18 00:41:53 +00001582bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001583 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001584
1585 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1586 if (Sym) {
1587 SMLoc S = Parser.getTok().getLoc();
1588 const MCExpr *Expr;
1589 if (Sym->isVariable())
1590 Expr = Sym->getVariableValue();
1591 else
1592 return false;
1593 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001594 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001595 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1596 const StringRef DefSymbol = Ref->getSymbol().getName();
1597 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001598 int RegNum = -1;
1599 APInt IntVal(32, -1);
1600 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1601 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001602 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001603 ? Mips::GPR64RegClassID
1604 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001605 else {
1606 // Lookup for the register with the corresponding name.
1607 switch (Kind) {
1608 case MipsOperand::Kind_AFGR64Regs:
1609 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001610 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001611 break;
1612 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001613 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001614 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001615 case MipsOperand::Kind_GPR64:
1616 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001617 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001618 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001619 break;
1620 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001621 if (RegNum > -1)
1622 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001623 }
Jack Carterd76b2372013-03-21 21:44:16 +00001624 if (RegNum > -1) {
1625 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001626 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1627 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001628 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001629 Operands.push_back(op);
1630 return true;
1631 }
1632 }
1633 } else if (Expr->getKind() == MCExpr::Constant) {
1634 Parser.Lex();
1635 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001636 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001637 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001638 Operands.push_back(op);
1639 return true;
1640 }
1641 }
1642 return false;
1643}
Jack Carterd0bd6422013-04-18 00:41:53 +00001644
Jack Carter873c7242013-01-12 01:03:14 +00001645MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001646MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001647 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001648}
1649
1650MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001651MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001652 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001653}
1654
Jack Carterdc1e35d2012-09-06 20:00:02 +00001655MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1656
1657 MCSymbolRefExpr::VariantKind VK
1658 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1659 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1660 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1661 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1662 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1663 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1664 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1665 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1666 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1667 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1668 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1669 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1670 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1671 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1672 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1673 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1674 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1675 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1676 .Default(MCSymbolRefExpr::VK_None);
1677
1678 return VK;
1679}
Jack Cartera63b16a2012-09-07 00:23:42 +00001680
Rafael Espindola870c4e92012-01-11 03:56:41 +00001681bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001682ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001683 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001684 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001685 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001686 Parser.eatToEndOfStatement();
1687 return Error(NameLoc, "Unknown instruction");
1688 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001689 // First operand in MCInst is instruction mnemonic.
1690 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001691
1692 // Read the remaining operands.
1693 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1694 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001695 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001696 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001697 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001698 return Error(Loc, "unexpected token in argument list");
1699 }
1700
Jack Carterd0bd6422013-04-18 00:41:53 +00001701 while (getLexer().is(AsmToken::Comma)) {
1702 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001703 // Parse and remember the operand.
1704 if (ParseOperand(Operands, Name)) {
1705 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001706 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001707 return Error(Loc, "unexpected token in argument list");
1708 }
1709 }
1710 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001711 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1712 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001713 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001714 return Error(Loc, "unexpected token in argument list");
1715 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001716 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001717 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001718}
1719
Jack Carter0b744b32012-10-04 02:29:46 +00001720bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001721 SMLoc Loc = getLexer().getLoc();
1722 Parser.eatToEndOfStatement();
1723 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001724}
1725
1726bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001727 // Line should look like: ".set noat".
1728 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001729 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001730 // eat noat
1731 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001732 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001733 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1734 reportParseError("unexpected token in statement");
1735 return false;
1736 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001737 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001738 return false;
1739}
Jack Carterd0bd6422013-04-18 00:41:53 +00001740
Jack Carter0b744b32012-10-04 02:29:46 +00001741bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001742 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001743 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001744 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001745 getParser().Lex();
1746 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001747 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001748 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001749 return false;
1750 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001751 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001752 if (getLexer().isNot(AsmToken::Dollar)) {
1753 reportParseError("unexpected token in statement");
1754 return false;
1755 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001756 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001757 const AsmToken &Reg = Parser.getTok();
1758 if (Reg.is(AsmToken::Identifier)) {
1759 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1760 } else if (Reg.is(AsmToken::Integer)) {
1761 AtRegNo = Reg.getIntVal();
1762 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001763 reportParseError("unexpected token in statement");
1764 return false;
1765 }
Jack Carter1ac53222013-02-20 23:11:17 +00001766
Jack Carterd0bd6422013-04-18 00:41:53 +00001767 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001768 reportParseError("unexpected token in statement");
1769 return false;
1770 }
1771
1772 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001773 reportParseError("unexpected token in statement");
1774 return false;
1775 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001776 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001777
1778 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1779 reportParseError("unexpected token in statement");
1780 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001781 }
1782 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001783 return false;
1784 } else {
1785 reportParseError("unexpected token in statement");
1786 return false;
1787 }
1788}
1789
1790bool MipsAsmParser::parseSetReorderDirective() {
1791 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001792 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001793 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1794 reportParseError("unexpected token in statement");
1795 return false;
1796 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001797 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001798 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001799 return false;
1800}
1801
1802bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001803 Parser.Lex();
1804 // If this is not the end of the statement, report an error.
1805 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1806 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001807 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001808 }
1809 Options.setNoreorder();
1810 Parser.Lex(); // Consume the EndOfStatement.
1811 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001812}
1813
1814bool MipsAsmParser::parseSetMacroDirective() {
1815 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001816 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001817 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1818 reportParseError("unexpected token in statement");
1819 return false;
1820 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001821 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001822 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001823 return false;
1824}
1825
1826bool MipsAsmParser::parseSetNoMacroDirective() {
1827 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001828 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001829 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1830 reportParseError("`noreorder' must be set before `nomacro'");
1831 return false;
1832 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001833 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00001834 reportParseError("`noreorder' must be set before `nomacro'");
1835 return false;
1836 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001837 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001838 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001839 return false;
1840}
Jack Carterd76b2372013-03-21 21:44:16 +00001841
1842bool MipsAsmParser::parseSetAssignment() {
1843 StringRef Name;
1844 const MCExpr *Value;
1845
1846 if (Parser.parseIdentifier(Name))
1847 reportParseError("expected identifier after .set");
1848
1849 if (getLexer().isNot(AsmToken::Comma))
1850 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00001851 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00001852
Jack Carter02593002013-05-28 22:21:05 +00001853 if (getLexer().is(AsmToken::Dollar)) {
1854 MCSymbol *Symbol;
1855 SMLoc DollarLoc = getLexer().getLoc();
1856 // Consume the dollar sign, and check for a following identifier.
1857 Parser.Lex();
1858 // We have a '$' followed by something, make sure they are adjacent.
1859 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1860 return true;
1861 StringRef Res = StringRef(DollarLoc.getPointer(),
1862 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1863 Symbol = getContext().GetOrCreateSymbol(Res);
1864 Parser.Lex();
1865 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1866 getContext());
1867 } else if (Parser.parseExpression(Value))
1868 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00001869
Jack Carterd0bd6422013-04-18 00:41:53 +00001870 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00001871 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00001872 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00001873 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00001874 Sym = getContext().GetOrCreateSymbol(Name);
1875 Sym->setVariableValue(Value);
1876
1877 return false;
1878}
Jack Carterd0bd6422013-04-18 00:41:53 +00001879
Jack Carter0b744b32012-10-04 02:29:46 +00001880bool MipsAsmParser::parseDirectiveSet() {
1881
Jack Carterd0bd6422013-04-18 00:41:53 +00001882 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00001883 const AsmToken &Tok = Parser.getTok();
1884
1885 if (Tok.getString() == "noat") {
1886 return parseSetNoAtDirective();
1887 } else if (Tok.getString() == "at") {
1888 return parseSetAtDirective();
1889 } else if (Tok.getString() == "reorder") {
1890 return parseSetReorderDirective();
1891 } else if (Tok.getString() == "noreorder") {
1892 return parseSetNoReorderDirective();
1893 } else if (Tok.getString() == "macro") {
1894 return parseSetMacroDirective();
1895 } else if (Tok.getString() == "nomacro") {
1896 return parseSetNoMacroDirective();
1897 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001898 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001899 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001900 return false;
1901 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001902 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001903 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001904 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001905 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001906 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00001907 parseSetAssignment();
1908 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001909 }
Jack Carter07c818d2013-01-25 01:31:34 +00001910
Jack Carter0b744b32012-10-04 02:29:46 +00001911 return true;
1912}
1913
Jack Carter07c818d2013-01-25 01:31:34 +00001914/// parseDirectiveWord
1915/// ::= .word [ expression (, expression)* ]
1916bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1917 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1918 for (;;) {
1919 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001920 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00001921 return true;
1922
1923 getParser().getStreamer().EmitValue(Value, Size);
1924
1925 if (getLexer().is(AsmToken::EndOfStatement))
1926 break;
1927
1928 // FIXME: Improve diagnostic.
1929 if (getLexer().isNot(AsmToken::Comma))
1930 return Error(L, "unexpected token in directive");
1931 Parser.Lex();
1932 }
1933 }
1934
1935 Parser.Lex();
1936 return false;
1937}
1938
Jack Carter0b744b32012-10-04 02:29:46 +00001939bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00001940
Jack Carter07c818d2013-01-25 01:31:34 +00001941 StringRef IDVal = DirectiveID.getString();
1942
Jack Carterd0bd6422013-04-18 00:41:53 +00001943 if (IDVal == ".ent") {
1944 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001945 Parser.Lex();
1946 return false;
1947 }
1948
Jack Carter07c818d2013-01-25 01:31:34 +00001949 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001950 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001951 Parser.Lex();
1952 return false;
1953 }
1954
Jack Carter07c818d2013-01-25 01:31:34 +00001955 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001956 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001957 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001958 return false;
1959 }
1960
Jack Carter07c818d2013-01-25 01:31:34 +00001961 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00001962 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00001963 }
1964
Jack Carter07c818d2013-01-25 01:31:34 +00001965 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001966 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001967 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001968 return false;
1969 }
1970
Jack Carter07c818d2013-01-25 01:31:34 +00001971 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001972 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001973 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001974 return false;
1975 }
1976
Jack Carter07c818d2013-01-25 01:31:34 +00001977 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001978 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001979 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001980 return false;
1981 }
1982
Jack Carter07c818d2013-01-25 01:31:34 +00001983 if (IDVal == ".word") {
1984 parseDirectiveWord(4, DirectiveID.getLoc());
1985 return false;
1986 }
1987
Rafael Espindola870c4e92012-01-11 03:56:41 +00001988 return true;
1989}
1990
Rafael Espindola870c4e92012-01-11 03:56:41 +00001991extern "C" void LLVMInitializeMipsAsmParser() {
1992 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1993 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1994 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1995 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1996}
Jack Carterb4dbc172012-09-05 23:34:03 +00001997
1998#define GET_REGISTER_MATCHER
1999#define GET_MATCHER_IMPLEMENTATION
2000#include "MipsGenAsmMatcher.inc"