blob: 3033fef5d858326f025a056a888957ae21e5df2c [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
Joey Gouly0e76fa72013-09-12 10:28:05 +000027namespace llvm {
28class MCInstrInfo;
29}
30
Rafael Espindola870c4e92012-01-11 03:56:41 +000031namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000032class MipsAssemblerOptions {
33public:
34 MipsAssemblerOptions():
35 aTReg(1), reorder(true), macro(true) {
36 }
Jack Carterb4dbc172012-09-05 23:34:03 +000037
Jack Carter0b744b32012-10-04 02:29:46 +000038 unsigned getATRegNum() {return aTReg;}
39 bool setATReg(unsigned Reg);
40
41 bool isReorder() {return reorder;}
42 void setReorder() {reorder = true;}
43 void setNoreorder() {reorder = false;}
44
45 bool isMacro() {return macro;}
46 void setMacro() {macro = true;}
47 void setNomacro() {macro = false;}
48
49private:
50 unsigned aTReg;
51 bool reorder;
52 bool macro;
53};
54}
55
56namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000057class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000058
Jack Carterb4dbc172012-09-05 23:34:03 +000059 MCSubtargetInfo &STI;
60 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000061 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000062 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000063
Akira Hatanaka7605630c2012-08-17 20:16:42 +000064#define GET_ASSEMBLER_HEADER
65#include "MipsGenAsmMatcher.inc"
66
Chad Rosier49963552012-10-13 00:26:04 +000067 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +000068 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000069 MCStreamer &Out, unsigned &ErrorInfo,
70 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000071
72 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
73
Chad Rosierf0e87202012-10-25 20:41:34 +000074 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
75 SMLoc NameLoc,
Akira Hatanaka7605630c2012-08-17 20:16:42 +000076 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000077
78 bool ParseDirective(AsmToken DirectiveID);
79
Jack Carterb4dbc172012-09-05 23:34:03 +000080 MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +000081 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
82 int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000083
84 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000085 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
86
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000087 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
88
89 MipsAsmParser::OperandMatchResultTy
90 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
91
Jack Carter873c7242013-01-12 01:03:14 +000092 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000093 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000094
95 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000096 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000097
98 MipsAsmParser::OperandMatchResultTy
99 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
100
101 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +0000102 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000103
Vladimir Medic233dd512013-06-24 10:05:34 +0000104 MipsAsmParser::OperandMatchResultTy
105 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
106
107 MipsAsmParser::OperandMatchResultTy
108 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
109
110 MipsAsmParser::OperandMatchResultTy
111 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
112
Vladimir Medic643b3982013-07-30 10:12:14 +0000113 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000114 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
115
116 MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +0000117 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
118
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000119 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000120 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000121
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000122 MipsAsmParser::OperandMatchResultTy
123 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
124
125 MipsAsmParser::OperandMatchResultTy
126 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
127
Vladimir Medic05bcde62013-09-16 10:29:42 +0000128 MipsAsmParser::OperandMatchResultTy
129 parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
130
Jack Carterd76b2372013-03-21 21:44:16 +0000131 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000132 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000133
Jack Carterb4dbc172012-09-05 23:34:03 +0000134 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
135 StringRef Mnemonic);
136
Jack Carter873c7242013-01-12 01:03:14 +0000137 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000138
139 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000140 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000141
Jack Carter30a59822012-10-04 04:03:53 +0000142 bool needsExpansion(MCInst &Inst);
143
144 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000145 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000146 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000147 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000148 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
149 SmallVectorImpl<MCInst> &Instructions);
150 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
151 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000152 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
153 SmallVectorImpl<MCInst> &Instructions,
154 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000155 bool reportParseError(StringRef ErrorMsg);
156
Jack Carterb5cf5902013-04-17 00:18:04 +0000157 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000158 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000159
Jack Carterb5cf5902013-04-17 00:18:04 +0000160 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
161
162 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000163 bool parseDirectiveSet();
164
165 bool parseSetAtDirective();
166 bool parseSetNoAtDirective();
167 bool parseSetMacroDirective();
168 bool parseSetNoMacroDirective();
169 bool parseSetReorderDirective();
170 bool parseSetNoReorderDirective();
171
Jack Carterd76b2372013-03-21 21:44:16 +0000172 bool parseSetAssignment();
173
Jack Carter07c818d2013-01-25 01:31:34 +0000174 bool parseDirectiveWord(unsigned Size, SMLoc L);
175
Jack Carterdc1e35d2012-09-06 20:00:02 +0000176 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000177
Jack Carterb4dbc172012-09-05 23:34:03 +0000178 bool isMips64() const {
179 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
180 }
181
Jack Cartera63b16a2012-09-07 00:23:42 +0000182 bool isFP64() const {
183 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
184 }
185
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000186 bool isN64() const {
187 return STI.getFeatureBits() & Mips::FeatureN64;
188 }
189
Jack Carter873c7242013-01-12 01:03:14 +0000190 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000191
Jack Carter1ac53222013-02-20 23:11:17 +0000192 int matchCPURegisterName(StringRef Symbol);
193
Jack Carter873c7242013-01-12 01:03:14 +0000194 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000195
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000196 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000197
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000198 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000199
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000200 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000201
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000202 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000203
Jack Carterd0bd6422013-04-18 00:41:53 +0000204 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000205
Jack Carter1ac53222013-02-20 23:11:17 +0000206 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000207
208 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000210public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000211 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
212 const MCInstrInfo &MII)
213 : MCTargetAsmParser(), STI(sti), Parser(parser),
214 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000215 // Initialize the set of available features.
216 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000217 }
218
Jack Carterb4dbc172012-09-05 23:34:03 +0000219 MCAsmParser &getParser() const { return Parser; }
220 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
221
Rafael Espindola870c4e92012-01-11 03:56:41 +0000222};
223}
224
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000225namespace {
226
227/// MipsOperand - Instances of this class represent a parsed Mips machine
228/// instruction.
229class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000230
Jack Carter873c7242013-01-12 01:03:14 +0000231public:
232 enum RegisterKind {
233 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000234 Kind_GPR32,
235 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000236 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000237 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000238 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000239 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000240 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000241 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000242 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000243 Kind_ACC64DSP,
244 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000245 Kind_HI32DSP,
246 Kind_COP2
Jack Carter873c7242013-01-12 01:03:14 +0000247 };
248
249private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000250 enum KindTy {
251 k_CondCode,
252 k_CoprocNum,
253 k_Immediate,
254 k_Memory,
255 k_PostIndexRegister,
256 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000257 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000258 k_Token
259 } Kind;
260
261 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000262
Eric Christopher8996c5d2013-03-15 00:42:55 +0000263 struct Token {
264 const char *Data;
265 unsigned Length;
266 };
267
268 struct RegOp {
269 unsigned RegNum;
270 RegisterKind Kind;
271 };
272
273 struct ImmOp {
274 const MCExpr *Val;
275 };
276
277 struct MemOp {
278 unsigned Base;
279 const MCExpr *Off;
280 };
281
Jack Carterb4dbc172012-09-05 23:34:03 +0000282 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000283 struct Token Tok;
284 struct RegOp Reg;
285 struct ImmOp Imm;
286 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000287 };
288
289 SMLoc StartLoc, EndLoc;
290
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000291public:
292 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000293 assert(N == 1 && "Invalid number of operands!");
294 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000295 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000296
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000297 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
298 assert(N == 1 && "Invalid number of operands!");
299 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
300 }
301
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000302 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000303 // Add as immediate when possible. Null MCExpr = 0.
304 if (Expr == 0)
305 Inst.addOperand(MCOperand::CreateImm(0));
306 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
307 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
308 else
309 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000310 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000311
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000312 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000313 assert(N == 1 && "Invalid number of operands!");
314 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000315 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000316 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000317
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000318 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000319 assert(N == 2 && "Invalid number of operands!");
320
321 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
322
323 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000324 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000325 }
326
327 bool isReg() const { return Kind == k_Register; }
328 bool isImm() const { return Kind == k_Immediate; }
329 bool isToken() const { return Kind == k_Token; }
330 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000331 bool isPtrReg() const { return Kind == k_PtrReg; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000332
333 StringRef getToken() const {
334 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000335 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000336 }
337
338 unsigned getReg() const {
339 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000340 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000341 }
342
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000343 unsigned getPtrReg() const {
344 assert((Kind == k_PtrReg) && "Invalid access!");
345 return Reg.RegNum;
346 }
347
Jack Carter873c7242013-01-12 01:03:14 +0000348 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000349 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000350 Reg.Kind = RegKind;
351 }
352
Jack Carterb4dbc172012-09-05 23:34:03 +0000353 const MCExpr *getImm() const {
354 assert((Kind == k_Immediate) && "Invalid access!");
355 return Imm.Val;
356 }
357
Jack Carterdc1e35d2012-09-06 20:00:02 +0000358 unsigned getMemBase() const {
359 assert((Kind == k_Memory) && "Invalid access!");
360 return Mem.Base;
361 }
362
363 const MCExpr *getMemOff() const {
364 assert((Kind == k_Memory) && "Invalid access!");
365 return Mem.Off;
366 }
367
Jack Carterb4dbc172012-09-05 23:34:03 +0000368 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
369 MipsOperand *Op = new MipsOperand(k_Token);
370 Op->Tok.Data = Str.data();
371 Op->Tok.Length = Str.size();
372 Op->StartLoc = S;
373 Op->EndLoc = S;
374 return Op;
375 }
376
377 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
378 MipsOperand *Op = new MipsOperand(k_Register);
379 Op->Reg.RegNum = RegNum;
380 Op->StartLoc = S;
381 Op->EndLoc = E;
382 return Op;
383 }
384
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000385 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
386 MipsOperand *Op = new MipsOperand(k_PtrReg);
387 Op->Reg.RegNum = RegNum;
388 Op->StartLoc = S;
389 Op->EndLoc = E;
390 return Op;
391 }
392
Jack Carterb4dbc172012-09-05 23:34:03 +0000393 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
394 MipsOperand *Op = new MipsOperand(k_Immediate);
395 Op->Imm.Val = Val;
396 Op->StartLoc = S;
397 Op->EndLoc = E;
398 return Op;
399 }
400
Jack Carterdc1e35d2012-09-06 20:00:02 +0000401 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
402 SMLoc S, SMLoc E) {
403 MipsOperand *Op = new MipsOperand(k_Memory);
404 Op->Mem.Base = Base;
405 Op->Mem.Off = Off;
406 Op->StartLoc = S;
407 Op->EndLoc = E;
408 return Op;
409 }
410
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000411 bool isGPR32Asm() const {
412 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000413 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000414 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000415 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
416 }
417
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000418 bool isGPR64Asm() const {
419 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000420 }
Jack Carter873c7242013-01-12 01:03:14 +0000421
422 bool isHWRegsAsm() const {
423 assert((Kind == k_Register) && "Invalid access!");
424 return Reg.Kind == Kind_HWRegs;
425 }
Jack Carter873c7242013-01-12 01:03:14 +0000426
Jack Carter873c7242013-01-12 01:03:14 +0000427 bool isCCRAsm() const {
428 assert((Kind == k_Register) && "Invalid access!");
429 return Reg.Kind == Kind_CCRRegs;
430 }
431
Vladimir Medic233dd512013-06-24 10:05:34 +0000432 bool isAFGR64Asm() const {
433 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
434 }
435
436 bool isFGR64Asm() const {
437 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
438 }
439
440 bool isFGR32Asm() const {
441 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
442 }
443
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000444 bool isFGRH32Asm() const {
445 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
446 }
447
Vladimir Medic643b3982013-07-30 10:12:14 +0000448 bool isFCCRegsAsm() const {
449 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
450 }
451
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000452 bool isACC64DSPAsm() const {
453 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000454 }
455
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000456 bool isLO32DSPAsm() const {
457 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
458 }
459
460 bool isHI32DSPAsm() const {
461 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
462 }
463
Vladimir Medic05bcde62013-09-16 10:29:42 +0000464 bool isCOP2Asm() const {
465 return Kind == k_Register && Reg.Kind == Kind_COP2;
466 }
467
Jack Carterb4dbc172012-09-05 23:34:03 +0000468 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000469 SMLoc getStartLoc() const {
470 return StartLoc;
471 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000472 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000473 SMLoc getEndLoc() const {
474 return EndLoc;
475 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000476
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000477 virtual void print(raw_ostream &OS) const {
478 llvm_unreachable("unimplemented!");
479 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000480}; // class MipsOperand
481} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000482
Jack Carter9e65aa32013-03-22 00:05:30 +0000483namespace llvm {
484extern const MCInstrDesc MipsInsts[];
485}
486static const MCInstrDesc &getInstDesc(unsigned Opcode) {
487 return MipsInsts[Opcode];
488}
489
490bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000491 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000492 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
493 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000494 if (MCID.hasDelaySlot() && Options.isReorder()) {
495 // If this instruction has a delay slot and .set reorder is active,
496 // emit a NOP after it.
497 Instructions.push_back(Inst);
498 MCInst NopInst;
499 NopInst.setOpcode(Mips::SLL);
500 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
501 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
502 NopInst.addOperand(MCOperand::CreateImm(0));
503 Instructions.push_back(NopInst);
504 return false;
505 }
506
Jack Carter9e65aa32013-03-22 00:05:30 +0000507 if (MCID.mayLoad() || MCID.mayStore()) {
508 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000509 // reference or immediate we may have to expand instructions.
510 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000511 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000512 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
513 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000514 MCOperand &Op = Inst.getOperand(i);
515 if (Op.isImm()) {
516 int MemOffset = Op.getImm();
517 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000518 // Offset can't exceed 16bit value.
519 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000520 return false;
521 }
522 } else if (Op.isExpr()) {
523 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000524 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000525 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000526 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000527 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000528 // Expand symbol.
529 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000530 return false;
531 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000532 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000533 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000534 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000535 }
536 }
537 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000538 } // for
539 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000540
541 if (needsExpansion(Inst))
542 expandInstruction(Inst, IDLoc, Instructions);
543 else
544 Instructions.push_back(Inst);
545
546 return false;
547}
548
Jack Carter30a59822012-10-04 04:03:53 +0000549bool MipsAsmParser::needsExpansion(MCInst &Inst) {
550
Jack Carterd0bd6422013-04-18 00:41:53 +0000551 switch (Inst.getOpcode()) {
552 case Mips::LoadImm32Reg:
553 case Mips::LoadAddr32Imm:
554 case Mips::LoadAddr32Reg:
555 return true;
556 default:
557 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000558 }
559}
Jack Carter92995f12012-10-06 00:53:28 +0000560
Jack Carter30a59822012-10-04 04:03:53 +0000561void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000562 SmallVectorImpl<MCInst> &Instructions) {
563 switch (Inst.getOpcode()) {
564 case Mips::LoadImm32Reg:
565 return expandLoadImm(Inst, IDLoc, Instructions);
566 case Mips::LoadAddr32Imm:
567 return expandLoadAddressImm(Inst, IDLoc, Instructions);
568 case Mips::LoadAddr32Reg:
569 return expandLoadAddressReg(Inst, IDLoc, Instructions);
570 }
Jack Carter30a59822012-10-04 04:03:53 +0000571}
Jack Carter92995f12012-10-06 00:53:28 +0000572
Jack Carter30a59822012-10-04 04:03:53 +0000573void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000574 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000575 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000576 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000577 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000578 const MCOperand &RegOp = Inst.getOperand(0);
579 assert(RegOp.isReg() && "expected register operand kind");
580
581 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000582 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000583 if (0 <= ImmValue && ImmValue <= 65535) {
584 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000585 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000586 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000587 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000588 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000589 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000590 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000591 } else if (ImmValue < 0 && ImmValue >= -32768) {
592 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000593 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000594 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000595 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000596 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000597 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000598 Instructions.push_back(tmpInst);
599 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000600 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000601 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000602 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000603 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000604 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
605 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000606 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000607 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000608 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000609 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
610 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
611 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
612 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000613 Instructions.push_back(tmpInst);
614 }
615}
Jack Carter92995f12012-10-06 00:53:28 +0000616
Jack Carter543fdf82012-10-09 23:29:45 +0000617void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000618 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000619 MCInst tmpInst;
620 const MCOperand &ImmOp = Inst.getOperand(2);
621 assert(ImmOp.isImm() && "expected immediate operand kind");
622 const MCOperand &SrcRegOp = Inst.getOperand(1);
623 assert(SrcRegOp.isReg() && "expected register operand kind");
624 const MCOperand &DstRegOp = Inst.getOperand(0);
625 assert(DstRegOp.isReg() && "expected register operand kind");
626 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000627 if (-32768 <= ImmValue && ImmValue <= 65535) {
628 // For -32768 <= j <= 65535.
629 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000630 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000631 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
632 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
633 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
634 Instructions.push_back(tmpInst);
635 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000636 // For any other value of j that is representable as a 32-bit integer.
637 // la d,j(s) => lui d,hi16(j)
638 // ori d,d,lo16(j)
639 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000640 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000641 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
642 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
643 Instructions.push_back(tmpInst);
644 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000645 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000646 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
647 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
648 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
649 Instructions.push_back(tmpInst);
650 tmpInst.clear();
651 tmpInst.setOpcode(Mips::ADDu);
652 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
653 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
654 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
655 Instructions.push_back(tmpInst);
656 }
657}
658
659void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000660 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000661 MCInst tmpInst;
662 const MCOperand &ImmOp = Inst.getOperand(1);
663 assert(ImmOp.isImm() && "expected immediate operand kind");
664 const MCOperand &RegOp = Inst.getOperand(0);
665 assert(RegOp.isReg() && "expected register operand kind");
666 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000667 if (-32768 <= ImmValue && ImmValue <= 65535) {
668 // For -32768 <= j <= 65535.
669 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000670 tmpInst.setOpcode(Mips::ADDiu);
671 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000672 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000673 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
674 Instructions.push_back(tmpInst);
675 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000676 // For any other value of j that is representable as a 32-bit integer.
677 // la d,j => lui d,hi16(j)
678 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000679 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000680 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
681 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
682 Instructions.push_back(tmpInst);
683 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000684 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000685 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
686 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
687 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
688 Instructions.push_back(tmpInst);
689 }
690}
691
Jack Carter9e65aa32013-03-22 00:05:30 +0000692void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000693 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000694 const MCSymbolRefExpr *SR;
695 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000696 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000697 const MCExpr *ExprOffset;
698 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000699 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
700 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000701 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000702 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
703 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000704 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000705 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
706 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000707 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000708 if (isImmOpnd) {
709 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
710 ImmOffset = Inst.getOperand(2).getImm();
711 LoOffset = ImmOffset & 0x0000ffff;
712 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000713 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000714 if (LoOffset & 0x8000)
715 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000716 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000717 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000718 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000719 TempInst.setLoc(IDLoc);
720 // 1st instruction in expansion is LUi. For load instruction we can use
721 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000722 // but for stores we must use $at.
723 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000724 TempInst.setOpcode(Mips::LUi);
725 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
726 if (isImmOpnd)
727 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
728 else {
729 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
730 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000731 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
732 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
733 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000734 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000735 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000736 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000737 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000738 }
739 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000740 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000741 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000742 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000743 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000744 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000745 TempInst.setOpcode(Mips::ADDu);
746 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
747 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
748 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
749 Instructions.push_back(TempInst);
750 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000751 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000752 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000753 TempInst.setOpcode(Inst.getOpcode());
754 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
755 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
756 if (isImmOpnd)
757 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
758 else {
759 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000760 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
761 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
762 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000763 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000764 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000765 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000766 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000767 }
768 }
769 Instructions.push_back(TempInst);
770 TempInst.clear();
771}
772
Rafael Espindola870c4e92012-01-11 03:56:41 +0000773bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000774MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000775 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000776 MCStreamer &Out, unsigned &ErrorInfo,
777 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000778 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000779 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000780 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000781 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000782
783 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000784 default:
785 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000786 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000787 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000788 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000789 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000790 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000791 return false;
792 }
793 case Match_MissingFeature:
794 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
795 return true;
796 case Match_InvalidOperand: {
797 SMLoc ErrorLoc = IDLoc;
798 if (ErrorInfo != ~0U) {
799 if (ErrorInfo >= Operands.size())
800 return Error(IDLoc, "too few operands for instruction");
801
Jack Carterd0bd6422013-04-18 00:41:53 +0000802 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
803 if (ErrorLoc == SMLoc())
804 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000805 }
806
807 return Error(ErrorLoc, "invalid operand for instruction");
808 }
809 case Match_MnemonicFail:
810 return Error(IDLoc, "invalid instruction");
811 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000812 return true;
813}
814
Jack Carter1ac53222013-02-20 23:11:17 +0000815int MipsAsmParser::matchCPURegisterName(StringRef Name) {
816 int CC;
817
818 if (Name == "at")
819 return getATReg();
820
821 CC = StringSwitch<unsigned>(Name)
822 .Case("zero", 0)
823 .Case("a0", 4)
824 .Case("a1", 5)
825 .Case("a2", 6)
826 .Case("a3", 7)
827 .Case("v0", 2)
828 .Case("v1", 3)
829 .Case("s0", 16)
830 .Case("s1", 17)
831 .Case("s2", 18)
832 .Case("s3", 19)
833 .Case("s4", 20)
834 .Case("s5", 21)
835 .Case("s6", 22)
836 .Case("s7", 23)
837 .Case("k0", 26)
838 .Case("k1", 27)
839 .Case("sp", 29)
840 .Case("fp", 30)
841 .Case("gp", 28)
842 .Case("ra", 31)
843 .Case("t0", 8)
844 .Case("t1", 9)
845 .Case("t2", 10)
846 .Case("t3", 11)
847 .Case("t4", 12)
848 .Case("t5", 13)
849 .Case("t6", 14)
850 .Case("t7", 15)
851 .Case("t8", 24)
852 .Case("t9", 25)
853 .Default(-1);
854
Jack Carterd0bd6422013-04-18 00:41:53 +0000855 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000856 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
857 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000858 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000859 CC += 4;
860
861 if (CC == -1 && isMips64())
862 CC = StringSwitch<unsigned>(Name)
863 .Case("a4", 8)
864 .Case("a5", 9)
865 .Case("a6", 10)
866 .Case("a7", 11)
867 .Case("kt0", 26)
868 .Case("kt1", 27)
869 .Case("s8", 30)
870 .Default(-1);
871
872 return CC;
873}
Jack Carterd0bd6422013-04-18 00:41:53 +0000874
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000875int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000876
Jack Cartera63b16a2012-09-07 00:23:42 +0000877 if (Name[0] == 'f') {
878 StringRef NumString = Name.substr(1);
879 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000880 if (NumString.getAsInteger(10, IntVal))
881 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000882 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000883 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000884 return IntVal;
885 }
886 return -1;
887}
Jack Cartera63b16a2012-09-07 00:23:42 +0000888
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000889int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
890
891 if (Name.startswith("fcc")) {
892 StringRef NumString = Name.substr(3);
893 unsigned IntVal;
894 if (NumString.getAsInteger(10, IntVal))
895 return -1; // This is not an integer.
896 if (IntVal > 7) // There are only 8 fcc registers.
897 return -1;
898 return IntVal;
899 }
900 return -1;
901}
902
903int MipsAsmParser::matchACRegisterName(StringRef Name) {
904
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000905 if (Name.startswith("ac")) {
906 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000907 unsigned IntVal;
908 if (NumString.getAsInteger(10, IntVal))
909 return -1; // This is not an integer.
910 if (IntVal > 3) // There are only 3 acc registers.
911 return -1;
912 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000913 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000914 return -1;
915}
Jack Carterd0bd6422013-04-18 00:41:53 +0000916
Vladimir Medic8cd17102013-06-20 11:21:49 +0000917int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
918
Vladimir Medic8cd17102013-06-20 11:21:49 +0000919 int CC;
920 CC = matchCPURegisterName(Name);
921 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000922 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
923 : Mips::GPR32RegClassID);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000924 CC= matchFPURegisterName(Name);
925 //TODO: decide about fpu register class
926 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
927 : Mips::FGR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000928}
929
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000930int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000931
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000932 switch (RegKind) {
933 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
934 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
935 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
936 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000937 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000938 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
939 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
940 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
941 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
942 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
943 default :return -1;
944 }
Jack Cartera63b16a2012-09-07 00:23:42 +0000945
Jack Cartera63b16a2012-09-07 00:23:42 +0000946}
Jack Carterb4dbc172012-09-05 23:34:03 +0000947
Jack Carter0b744b32012-10-04 02:29:46 +0000948bool MipsAssemblerOptions::setATReg(unsigned Reg) {
949 if (Reg > 31)
950 return false;
951
952 aTReg = Reg;
953 return true;
954}
955
Jack Carter1ac53222013-02-20 23:11:17 +0000956int MipsAsmParser::getATReg() {
957 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +0000958}
959
Jack Carterd0bd6422013-04-18 00:41:53 +0000960unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +0000961 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +0000962}
963
Jack Carter873c7242013-01-12 01:03:14 +0000964int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000965 if (RegNum >
966 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +0000967 return -1;
968
Jack Carter873c7242013-01-12 01:03:14 +0000969 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +0000970}
971
Jack Carter873c7242013-01-12 01:03:14 +0000972int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000973 const AsmToken &Tok = Parser.getTok();
974 int RegNum = -1;
975
976 if (Tok.is(AsmToken::Identifier)) {
977 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +0000978 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000979 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +0000980 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000981 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +0000982 return RegNum;
983}
984
Jack Carterd0bd6422013-04-18 00:41:53 +0000985bool MipsAsmParser::tryParseRegisterOperand(
986 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000987
988 SMLoc S = Parser.getTok().getLoc();
989 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +0000990
Jack Carter873c7242013-01-12 01:03:14 +0000991 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000992 if (RegNo == -1)
993 return true;
994
Jack Carter873c7242013-01-12 01:03:14 +0000995 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +0000996 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +0000997 Parser.Lex(); // Eat register token.
998 return false;
999}
1000
1001bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1002 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001003 // Check if the current operand has a custom associated parser, if so, try to
1004 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001005 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1006 if (ResTy == MatchOperand_Success)
1007 return false;
1008 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1009 // there was a match, but an error occurred, in which case, just return that
1010 // the operand parsing failed.
1011 if (ResTy == MatchOperand_ParseFail)
1012 return true;
1013
1014 switch (getLexer().getKind()) {
1015 default:
1016 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1017 return true;
1018 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001019 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001020 SMLoc S = Parser.getTok().getLoc();
1021 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001022 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001023 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001024 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001025 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001026 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001027 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001028 if (getLexer().isNot(AsmToken::Dollar))
1029 return true;
1030
Jack Carterd0bd6422013-04-18 00:41:53 +00001031 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001032 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001033 return true;
1034
1035 if (!getLexer().is(AsmToken::RParen))
1036 return true;
1037
1038 S = Parser.getTok().getLoc();
1039 Operands.push_back(MipsOperand::CreateToken(")", S));
1040 Parser.Lex();
1041 }
1042 return false;
1043 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001044 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001045 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001046 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001047 return true;
1048
Jack Carter873c7242013-01-12 01:03:14 +00001049 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001050
Benjamin Kramerfa530572012-09-07 09:47:42 +00001051 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001052
Jack Carterd0bd6422013-04-18 00:41:53 +00001053 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001054 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001055 getContext());
1056
1057 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1058 return false;
1059 }
1060 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001061 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001062 // we need to assigne the propper RegisterKind.
1063 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1064 return false;
1065 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001066 case AsmToken::LParen:
1067 case AsmToken::Minus:
1068 case AsmToken::Plus:
1069 case AsmToken::Integer:
1070 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001071 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001072 const MCExpr *IdVal;
1073 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001074 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001075 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001076 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001077 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1078 return false;
1079 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001080 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001081 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001082 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001083 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001084 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001085 return true;
1086
Jack Carter873c7242013-01-12 01:03:14 +00001087 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1088
Jack Carterdc1e35d2012-09-06 20:00:02 +00001089 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1090 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001091 } // case AsmToken::Percent
1092 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001093 return true;
1094}
1095
Jack Carterb5cf5902013-04-17 00:18:04 +00001096const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1097 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001098 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001099 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001100 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001101 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001102 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001103 short Val = MCE->getValue();
1104 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001105 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001106 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001107 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001108 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001109 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001110 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001111 if (LoSign)
1112 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001113 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001114 } else {
1115 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001116 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001117 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001118 }
1119
Jack Carterb5cf5902013-04-17 00:18:04 +00001120 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001121 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001122 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001123 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001124 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001125 return Res;
1126 }
1127
1128 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001129 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1130 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001131 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1132 return Res;
1133 }
1134
1135 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001136 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1137 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1138 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001139 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001140 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001141 return Expr;
1142}
1143
1144bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1145
1146 switch (Expr->getKind()) {
1147 case MCExpr::Constant:
1148 return true;
1149 case MCExpr::SymbolRef:
1150 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1151 case MCExpr::Binary:
1152 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1153 if (!isEvaluated(BE->getLHS()))
1154 return false;
1155 return isEvaluated(BE->getRHS());
1156 }
1157 case MCExpr::Unary:
1158 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1159 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001160 return false;
1161 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001162 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001163}
Jack Carterd0bd6422013-04-18 00:41:53 +00001164
Jack Carterb5cf5902013-04-17 00:18:04 +00001165bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001166 Parser.Lex(); // Eat the % token.
1167 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001168 if (Tok.isNot(AsmToken::Identifier))
1169 return true;
1170
1171 std::string Str = Tok.getIdentifier().str();
1172
Jack Carterd0bd6422013-04-18 00:41:53 +00001173 Parser.Lex(); // Eat the identifier.
1174 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001175 const MCExpr *IdVal;
1176 SMLoc EndLoc;
1177
1178 if (getLexer().getKind() == AsmToken::LParen) {
1179 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001180 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001181 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001182 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001183 const AsmToken &nextTok = Parser.getTok();
1184 if (nextTok.isNot(AsmToken::Identifier))
1185 return true;
1186 Str += "(%";
1187 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001188 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001189 if (getLexer().getKind() != AsmToken::LParen)
1190 return true;
1191 } else
1192 break;
1193 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001194 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001195 return true;
1196
1197 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001198 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001199
1200 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001201 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001202
Jack Carterd0bd6422013-04-18 00:41:53 +00001203 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001204 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001205}
1206
Jack Carterb4dbc172012-09-05 23:34:03 +00001207bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1208 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001209 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001210 RegNo = tryParseRegister(isMips64());
1211 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001212 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001213}
1214
Jack Carterb5cf5902013-04-17 00:18:04 +00001215bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001216 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001217 bool Result = true;
1218
1219 while (getLexer().getKind() == AsmToken::LParen)
1220 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001221
Jack Carterd0bd6422013-04-18 00:41:53 +00001222 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001223 default:
1224 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001225 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001226 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001227 case AsmToken::Integer:
1228 case AsmToken::Minus:
1229 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001230 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001231 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001232 else
1233 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001234 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001235 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001236 break;
Jack Carter873c7242013-01-12 01:03:14 +00001237 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001238 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001239 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001240 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001241}
1242
Jack Carterb4dbc172012-09-05 23:34:03 +00001243MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001244 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001245
1246 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001247 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001248 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001249 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001250 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001251 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001252
Jack Carterb5cf5902013-04-17 00:18:04 +00001253 if (getLexer().getKind() == AsmToken::LParen) {
1254 Parser.Lex();
1255 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001256 }
1257
Jack Carterb5cf5902013-04-17 00:18:04 +00001258 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001259 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001260 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001261
Jack Carterd0bd6422013-04-18 00:41:53 +00001262 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001263 if (Tok.isNot(AsmToken::LParen)) {
1264 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1265 if (Mnemonic->getToken() == "la") {
1266 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001267 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001268 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1269 return MatchOperand_Success;
1270 }
1271 if (Tok.is(AsmToken::EndOfStatement)) {
1272 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001273 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001274
Jack Carterd0bd6422013-04-18 00:41:53 +00001275 // Zero register assumed, add a memory operand with ZERO as its base.
1276 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1277 : Mips::ZERO,
1278 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001279 return MatchOperand_Success;
1280 }
1281 Error(Parser.getTok().getLoc(), "'(' expected");
1282 return MatchOperand_ParseFail;
1283 }
1284
Jack Carterd0bd6422013-04-18 00:41:53 +00001285 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001286 }
1287
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001288 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1289 (int) MipsOperand::Kind_GPR32);
1290 if (Res != MatchOperand_Success)
1291 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001292
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001293 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001294 Error(Parser.getTok().getLoc(), "')' expected");
1295 return MatchOperand_ParseFail;
1296 }
1297
Jack Carter873c7242013-01-12 01:03:14 +00001298 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1299
Jack Carterd0bd6422013-04-18 00:41:53 +00001300 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001301
1302 if (IdVal == 0)
1303 IdVal = MCConstantExpr::Create(0, getContext());
1304
Jack Carterd0bd6422013-04-18 00:41:53 +00001305 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001306 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1307 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001308 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001309 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001310 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001311 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1312 int64_t Imm;
1313 if (IdVal->EvaluateAsAbsolute(Imm))
1314 IdVal = MCConstantExpr::Create(Imm, getContext());
1315 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1316 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1317 getContext());
1318 }
1319
Jack Carterdc1e35d2012-09-06 20:00:02 +00001320 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1321 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001322 return MatchOperand_Success;
1323}
1324
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001325bool
1326MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1327 int RegKind) {
1328 // If the first token is not '$' we have an error.
1329 if (Parser.getTok().isNot(AsmToken::Dollar))
1330 return false;
1331
1332 SMLoc S = Parser.getTok().getLoc();
1333 Parser.Lex();
1334 AsmToken::TokenKind TkKind = getLexer().getKind();
1335 int Reg;
1336
1337 if (TkKind == AsmToken::Integer) {
1338 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1339 regKindToRegClass(RegKind));
1340 if (Reg == -1)
1341 return false;
1342 } else if (TkKind == AsmToken::Identifier) {
1343 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1344 return false;
1345 Reg = getReg(regKindToRegClass(RegKind), Reg);
1346 } else {
1347 return false;
1348 }
1349
1350 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1351 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1352 Operands.push_back(Op);
1353 Parser.Lex();
1354 return true;
1355}
1356
1357MipsAsmParser::OperandMatchResultTy
1358MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1359 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1360 MipsOperand::Kind_GPR32;
1361
1362 // Parse index register.
1363 if (!parsePtrReg(Operands, RegKind))
1364 return MatchOperand_NoMatch;
1365
1366 // Parse '('.
1367 if (Parser.getTok().isNot(AsmToken::LParen))
1368 return MatchOperand_NoMatch;
1369
1370 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1371 Parser.Lex();
1372
1373 // Parse base register.
1374 if (!parsePtrReg(Operands, RegKind))
1375 return MatchOperand_NoMatch;
1376
1377 // Parse ')'.
1378 if (Parser.getTok().isNot(AsmToken::RParen))
1379 return MatchOperand_NoMatch;
1380
1381 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1382 Parser.Lex();
1383
1384 return MatchOperand_Success;
1385}
1386
Jack Carter873c7242013-01-12 01:03:14 +00001387MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001388MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1389 int RegKind) {
1390 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001391 if (getLexer().getKind() == AsmToken::Identifier
1392 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001393 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001394 return MatchOperand_Success;
1395 return MatchOperand_NoMatch;
1396 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001397 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001398 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001399 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001400 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001401 if (!hasConsumedDollar) {
1402 Parser.Lex(); // Eat the '$'
1403 hasConsumedDollar = true;
1404 }
1405 if (getLexer().getKind() == AsmToken::Identifier) {
1406 int RegNum = -1;
1407 std::string RegName = Parser.getTok().getString().lower();
1408 // Match register by name
1409 switch (RegKind) {
1410 case MipsOperand::Kind_GPR32:
1411 case MipsOperand::Kind_GPR64:
1412 RegNum = matchCPURegisterName(RegName);
1413 break;
1414 case MipsOperand::Kind_AFGR64Regs:
1415 case MipsOperand::Kind_FGR64Regs:
1416 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001417 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001418 RegNum = matchFPURegisterName(RegName);
1419 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1420 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001421 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1422 && !isFP64())
1423 if (RegNum != -1 && RegNum %2 != 0)
1424 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001425 break;
1426 case MipsOperand::Kind_FCCRegs:
1427 RegNum = matchFCCRegisterName(RegName);
1428 break;
1429 case MipsOperand::Kind_ACC64DSP:
1430 RegNum = matchACRegisterName(RegName);
1431 break;
1432 default: break; // No match, value is set to -1.
1433 }
1434 // No match found, return _NoMatch to give a chance to other round.
1435 if (RegNum < 0)
1436 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001437
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001438 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1439 if (RegVal == -1)
1440 return MatchOperand_NoMatch;
1441
1442 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1443 Parser.getTok().getLoc());
1444 Op->setRegKind(Kind);
1445 Operands.push_back(Op);
1446 hasConsumedDollar = false;
1447 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001448 return MatchOperand_Success;
1449 } else if (getLexer().getKind() == AsmToken::Integer) {
1450 unsigned RegNum = Parser.getTok().getIntVal();
1451 if (Kind == MipsOperand::Kind_HWRegs) {
1452 if (RegNum != 29)
1453 return MatchOperand_NoMatch;
1454 // Only hwreg 29 is supported, found at index 0.
1455 RegNum = 0;
1456 }
1457 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1458 if (Reg == -1)
1459 return MatchOperand_NoMatch;
1460 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1461 Op->setRegKind(Kind);
1462 Operands.push_back(Op);
1463 hasConsumedDollar = false;
1464 Parser.Lex(); // Eat the register number.
1465 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001466 && (getLexer().is(AsmToken::LParen))) {
1467 // Check if it is indexed addressing operand.
1468 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1469 Parser.Lex(); // Eat the parenthesis.
1470 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1471 return MatchOperand_NoMatch;
1472 if (getLexer().isNot(AsmToken::RParen))
1473 return MatchOperand_NoMatch;
1474 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1475 Parser.Lex();
1476 }
Jack Carter873c7242013-01-12 01:03:14 +00001477 return MatchOperand_Success;
1478 }
1479 return MatchOperand_NoMatch;
1480}
Vladimir Medic64828a12013-07-16 10:07:14 +00001481
Vladimir Medic8cd17102013-06-20 11:21:49 +00001482MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001483MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001484
1485 if (!isMips64())
1486 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001487 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001488}
1489
1490MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001491MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1492 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001493}
Jack Carter873c7242013-01-12 01:03:14 +00001494
Vladimir Medic233dd512013-06-24 10:05:34 +00001495MipsAsmParser::OperandMatchResultTy
1496MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1497
1498 if (isFP64())
1499 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001500 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1501}
1502
1503MipsAsmParser::OperandMatchResultTy
1504MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1505 if (!isFP64())
1506 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001507 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1508}
1509
1510MipsAsmParser::OperandMatchResultTy
1511MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001512 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1513}
1514
Vladimir Medic643b3982013-07-30 10:12:14 +00001515MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001516MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1517 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1518}
1519
1520MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001521MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001522 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001523}
1524
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001525MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001526MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001527 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001528}
1529
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001530MipsAsmParser::OperandMatchResultTy
1531MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1532 // If the first token is not '$' we have an error.
1533 if (Parser.getTok().isNot(AsmToken::Dollar))
1534 return MatchOperand_NoMatch;
1535
1536 SMLoc S = Parser.getTok().getLoc();
1537 Parser.Lex(); // Eat the '$'
1538
1539 const AsmToken &Tok = Parser.getTok(); // Get next token.
1540
1541 if (Tok.isNot(AsmToken::Identifier))
1542 return MatchOperand_NoMatch;
1543
1544 if (!Tok.getIdentifier().startswith("ac"))
1545 return MatchOperand_NoMatch;
1546
1547 StringRef NumString = Tok.getIdentifier().substr(2);
1548
1549 unsigned IntVal;
1550 if (NumString.getAsInteger(10, IntVal))
1551 return MatchOperand_NoMatch;
1552
1553 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1554
1555 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1556 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1557 Operands.push_back(Op);
1558
1559 Parser.Lex(); // Eat the register number.
1560 return MatchOperand_Success;
1561}
1562
1563MipsAsmParser::OperandMatchResultTy
1564MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1565 // If the first token is not '$' we have an error.
1566 if (Parser.getTok().isNot(AsmToken::Dollar))
1567 return MatchOperand_NoMatch;
1568
1569 SMLoc S = Parser.getTok().getLoc();
1570 Parser.Lex(); // Eat the '$'
1571
1572 const AsmToken &Tok = Parser.getTok(); // Get next token.
1573
1574 if (Tok.isNot(AsmToken::Identifier))
1575 return MatchOperand_NoMatch;
1576
1577 if (!Tok.getIdentifier().startswith("ac"))
1578 return MatchOperand_NoMatch;
1579
1580 StringRef NumString = Tok.getIdentifier().substr(2);
1581
1582 unsigned IntVal;
1583 if (NumString.getAsInteger(10, IntVal))
1584 return MatchOperand_NoMatch;
1585
1586 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1587
1588 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1589 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1590 Operands.push_back(Op);
1591
1592 Parser.Lex(); // Eat the register number.
1593 return MatchOperand_Success;
1594}
1595
Vladimir Medic05bcde62013-09-16 10:29:42 +00001596MipsAsmParser::OperandMatchResultTy
1597MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1598 // If the first token is not '$' we have an error.
1599 if (Parser.getTok().isNot(AsmToken::Dollar))
1600 return MatchOperand_NoMatch;
1601
1602 SMLoc S = Parser.getTok().getLoc();
1603 Parser.Lex(); // Eat the '$'
1604
1605 const AsmToken &Tok = Parser.getTok(); // Get next token.
1606
1607 if (Tok.isNot(AsmToken::Integer))
1608 return MatchOperand_NoMatch;
1609
1610 unsigned IntVal = Tok.getIntVal();
1611
1612 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1613
1614 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1615 Op->setRegKind(MipsOperand::Kind_COP2);
1616 Operands.push_back(Op);
1617
1618 Parser.Lex(); // Eat the register number.
1619 return MatchOperand_Success;
1620}
1621
Jack Carterd0bd6422013-04-18 00:41:53 +00001622bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001623 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001624
1625 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1626 if (Sym) {
1627 SMLoc S = Parser.getTok().getLoc();
1628 const MCExpr *Expr;
1629 if (Sym->isVariable())
1630 Expr = Sym->getVariableValue();
1631 else
1632 return false;
1633 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001634 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001635 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1636 const StringRef DefSymbol = Ref->getSymbol().getName();
1637 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001638 int RegNum = -1;
1639 APInt IntVal(32, -1);
1640 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1641 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001642 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001643 ? Mips::GPR64RegClassID
1644 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001645 else {
1646 // Lookup for the register with the corresponding name.
1647 switch (Kind) {
1648 case MipsOperand::Kind_AFGR64Regs:
1649 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001650 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001651 break;
1652 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001653 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001654 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001655 case MipsOperand::Kind_GPR64:
1656 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001657 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001658 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001659 break;
1660 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001661 if (RegNum > -1)
1662 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001663 }
Jack Carterd76b2372013-03-21 21:44:16 +00001664 if (RegNum > -1) {
1665 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001666 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1667 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001668 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001669 Operands.push_back(op);
1670 return true;
1671 }
1672 }
1673 } else if (Expr->getKind() == MCExpr::Constant) {
1674 Parser.Lex();
1675 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001676 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001677 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001678 Operands.push_back(op);
1679 return true;
1680 }
1681 }
1682 return false;
1683}
Jack Carterd0bd6422013-04-18 00:41:53 +00001684
Jack Carter873c7242013-01-12 01:03:14 +00001685MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001686MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001687 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001688}
1689
1690MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001691MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001692 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001693}
1694
Jack Carterdc1e35d2012-09-06 20:00:02 +00001695MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1696
1697 MCSymbolRefExpr::VariantKind VK
1698 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1699 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1700 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1701 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1702 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1703 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1704 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1705 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1706 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1707 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1708 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1709 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1710 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1711 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1712 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1713 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1714 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1715 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1716 .Default(MCSymbolRefExpr::VK_None);
1717
1718 return VK;
1719}
Jack Cartera63b16a2012-09-07 00:23:42 +00001720
Rafael Espindola870c4e92012-01-11 03:56:41 +00001721bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001722ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001723 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001724 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001725 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001726 Parser.eatToEndOfStatement();
1727 return Error(NameLoc, "Unknown instruction");
1728 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001729 // First operand in MCInst is instruction mnemonic.
1730 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001731
1732 // Read the remaining operands.
1733 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1734 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001735 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001736 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001737 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001738 return Error(Loc, "unexpected token in argument list");
1739 }
1740
Jack Carterd0bd6422013-04-18 00:41:53 +00001741 while (getLexer().is(AsmToken::Comma)) {
1742 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001743 // Parse and remember the operand.
1744 if (ParseOperand(Operands, Name)) {
1745 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001746 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001747 return Error(Loc, "unexpected token in argument list");
1748 }
1749 }
1750 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001751 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1752 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001753 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001754 return Error(Loc, "unexpected token in argument list");
1755 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001756 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001757 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001758}
1759
Jack Carter0b744b32012-10-04 02:29:46 +00001760bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001761 SMLoc Loc = getLexer().getLoc();
1762 Parser.eatToEndOfStatement();
1763 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001764}
1765
1766bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001767 // Line should look like: ".set noat".
1768 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001769 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001770 // eat noat
1771 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001772 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001773 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1774 reportParseError("unexpected token in statement");
1775 return false;
1776 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001777 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001778 return false;
1779}
Jack Carterd0bd6422013-04-18 00:41:53 +00001780
Jack Carter0b744b32012-10-04 02:29:46 +00001781bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001782 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001783 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001784 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001785 getParser().Lex();
1786 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001787 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001788 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001789 return false;
1790 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001791 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001792 if (getLexer().isNot(AsmToken::Dollar)) {
1793 reportParseError("unexpected token in statement");
1794 return false;
1795 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001796 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001797 const AsmToken &Reg = Parser.getTok();
1798 if (Reg.is(AsmToken::Identifier)) {
1799 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1800 } else if (Reg.is(AsmToken::Integer)) {
1801 AtRegNo = Reg.getIntVal();
1802 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001803 reportParseError("unexpected token in statement");
1804 return false;
1805 }
Jack Carter1ac53222013-02-20 23:11:17 +00001806
Jack Carterd0bd6422013-04-18 00:41:53 +00001807 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001808 reportParseError("unexpected token in statement");
1809 return false;
1810 }
1811
1812 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001813 reportParseError("unexpected token in statement");
1814 return false;
1815 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001816 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001817
1818 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1819 reportParseError("unexpected token in statement");
1820 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001821 }
1822 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001823 return false;
1824 } else {
1825 reportParseError("unexpected token in statement");
1826 return false;
1827 }
1828}
1829
1830bool MipsAsmParser::parseSetReorderDirective() {
1831 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001832 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001833 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1834 reportParseError("unexpected token in statement");
1835 return false;
1836 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001837 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001838 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001839 return false;
1840}
1841
1842bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001843 Parser.Lex();
1844 // If this is not the end of the statement, report an error.
1845 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1846 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001847 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001848 }
1849 Options.setNoreorder();
1850 Parser.Lex(); // Consume the EndOfStatement.
1851 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001852}
1853
1854bool MipsAsmParser::parseSetMacroDirective() {
1855 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001856 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001857 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1858 reportParseError("unexpected token in statement");
1859 return false;
1860 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001861 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001862 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001863 return false;
1864}
1865
1866bool MipsAsmParser::parseSetNoMacroDirective() {
1867 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001868 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001869 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1870 reportParseError("`noreorder' must be set before `nomacro'");
1871 return false;
1872 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001873 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00001874 reportParseError("`noreorder' must be set before `nomacro'");
1875 return false;
1876 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001877 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001878 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001879 return false;
1880}
Jack Carterd76b2372013-03-21 21:44:16 +00001881
1882bool MipsAsmParser::parseSetAssignment() {
1883 StringRef Name;
1884 const MCExpr *Value;
1885
1886 if (Parser.parseIdentifier(Name))
1887 reportParseError("expected identifier after .set");
1888
1889 if (getLexer().isNot(AsmToken::Comma))
1890 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00001891 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00001892
Jack Carter02593002013-05-28 22:21:05 +00001893 if (getLexer().is(AsmToken::Dollar)) {
1894 MCSymbol *Symbol;
1895 SMLoc DollarLoc = getLexer().getLoc();
1896 // Consume the dollar sign, and check for a following identifier.
1897 Parser.Lex();
1898 // We have a '$' followed by something, make sure they are adjacent.
1899 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1900 return true;
1901 StringRef Res = StringRef(DollarLoc.getPointer(),
1902 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1903 Symbol = getContext().GetOrCreateSymbol(Res);
1904 Parser.Lex();
1905 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1906 getContext());
1907 } else if (Parser.parseExpression(Value))
1908 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00001909
Jack Carterd0bd6422013-04-18 00:41:53 +00001910 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00001911 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00001912 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00001913 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00001914 Sym = getContext().GetOrCreateSymbol(Name);
1915 Sym->setVariableValue(Value);
1916
1917 return false;
1918}
Jack Carterd0bd6422013-04-18 00:41:53 +00001919
Jack Carter0b744b32012-10-04 02:29:46 +00001920bool MipsAsmParser::parseDirectiveSet() {
1921
Jack Carterd0bd6422013-04-18 00:41:53 +00001922 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00001923 const AsmToken &Tok = Parser.getTok();
1924
1925 if (Tok.getString() == "noat") {
1926 return parseSetNoAtDirective();
1927 } else if (Tok.getString() == "at") {
1928 return parseSetAtDirective();
1929 } else if (Tok.getString() == "reorder") {
1930 return parseSetReorderDirective();
1931 } else if (Tok.getString() == "noreorder") {
1932 return parseSetNoReorderDirective();
1933 } else if (Tok.getString() == "macro") {
1934 return parseSetMacroDirective();
1935 } else if (Tok.getString() == "nomacro") {
1936 return parseSetNoMacroDirective();
1937 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001938 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001939 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001940 return false;
1941 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001942 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001943 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001944 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001945 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001946 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00001947 parseSetAssignment();
1948 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001949 }
Jack Carter07c818d2013-01-25 01:31:34 +00001950
Jack Carter0b744b32012-10-04 02:29:46 +00001951 return true;
1952}
1953
Jack Carter07c818d2013-01-25 01:31:34 +00001954/// parseDirectiveWord
1955/// ::= .word [ expression (, expression)* ]
1956bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1957 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1958 for (;;) {
1959 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001960 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00001961 return true;
1962
1963 getParser().getStreamer().EmitValue(Value, Size);
1964
1965 if (getLexer().is(AsmToken::EndOfStatement))
1966 break;
1967
1968 // FIXME: Improve diagnostic.
1969 if (getLexer().isNot(AsmToken::Comma))
1970 return Error(L, "unexpected token in directive");
1971 Parser.Lex();
1972 }
1973 }
1974
1975 Parser.Lex();
1976 return false;
1977}
1978
Jack Carter0b744b32012-10-04 02:29:46 +00001979bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00001980
Jack Carter07c818d2013-01-25 01:31:34 +00001981 StringRef IDVal = DirectiveID.getString();
1982
Jack Carterd0bd6422013-04-18 00:41:53 +00001983 if (IDVal == ".ent") {
1984 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001985 Parser.Lex();
1986 return false;
1987 }
1988
Jack Carter07c818d2013-01-25 01:31:34 +00001989 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001990 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001991 Parser.Lex();
1992 return false;
1993 }
1994
Jack Carter07c818d2013-01-25 01:31:34 +00001995 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001996 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001997 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001998 return false;
1999 }
2000
Jack Carter07c818d2013-01-25 01:31:34 +00002001 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002002 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002003 }
2004
Jack Carter07c818d2013-01-25 01:31:34 +00002005 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002006 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002007 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002008 return false;
2009 }
2010
Jack Carter07c818d2013-01-25 01:31:34 +00002011 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002012 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002013 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002014 return false;
2015 }
2016
Jack Carter07c818d2013-01-25 01:31:34 +00002017 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002018 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002019 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002020 return false;
2021 }
2022
Jack Carter07c818d2013-01-25 01:31:34 +00002023 if (IDVal == ".word") {
2024 parseDirectiveWord(4, DirectiveID.getLoc());
2025 return false;
2026 }
2027
Rafael Espindola870c4e92012-01-11 03:56:41 +00002028 return true;
2029}
2030
Rafael Espindola870c4e92012-01-11 03:56:41 +00002031extern "C" void LLVMInitializeMipsAsmParser() {
2032 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2033 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2034 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2035 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2036}
Jack Carterb4dbc172012-09-05 23:34:03 +00002037
2038#define GET_REGISTER_MATCHER
2039#define GET_MATCHER_IMPLEMENTATION
2040#include "MipsGenAsmMatcher.inc"