blob: c4ce4ff5b34ff9acbda4f6393bbe97464ab5da08 [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
Jack Carterd76b2372013-03-21 21:44:16 +0000128 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000129 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000130
Jack Carterb4dbc172012-09-05 23:34:03 +0000131 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
132 StringRef Mnemonic);
133
Jack Carter873c7242013-01-12 01:03:14 +0000134 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000135
136 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000137 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000138
Jack Carter30a59822012-10-04 04:03:53 +0000139 bool needsExpansion(MCInst &Inst);
140
141 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000142 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000143 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000144 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000145 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
146 SmallVectorImpl<MCInst> &Instructions);
147 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
148 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000149 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
150 SmallVectorImpl<MCInst> &Instructions,
151 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000152 bool reportParseError(StringRef ErrorMsg);
153
Jack Carterb5cf5902013-04-17 00:18:04 +0000154 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000155 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000156
Jack Carterb5cf5902013-04-17 00:18:04 +0000157 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
158
159 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000160 bool parseDirectiveSet();
161
162 bool parseSetAtDirective();
163 bool parseSetNoAtDirective();
164 bool parseSetMacroDirective();
165 bool parseSetNoMacroDirective();
166 bool parseSetReorderDirective();
167 bool parseSetNoReorderDirective();
168
Jack Carterd76b2372013-03-21 21:44:16 +0000169 bool parseSetAssignment();
170
Jack Carter07c818d2013-01-25 01:31:34 +0000171 bool parseDirectiveWord(unsigned Size, SMLoc L);
172
Jack Carterdc1e35d2012-09-06 20:00:02 +0000173 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000174
Jack Carterb4dbc172012-09-05 23:34:03 +0000175 bool isMips64() const {
176 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
177 }
178
Jack Cartera63b16a2012-09-07 00:23:42 +0000179 bool isFP64() const {
180 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
181 }
182
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000183 bool isN64() const {
184 return STI.getFeatureBits() & Mips::FeatureN64;
185 }
186
Jack Carter873c7242013-01-12 01:03:14 +0000187 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000188
Jack Carter1ac53222013-02-20 23:11:17 +0000189 int matchCPURegisterName(StringRef Symbol);
190
Jack Carter873c7242013-01-12 01:03:14 +0000191 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000192
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000193 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000194
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000195 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000196
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000197 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000198
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000199 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000200
Jack Carterd0bd6422013-04-18 00:41:53 +0000201 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000202
Jack Carter1ac53222013-02-20 23:11:17 +0000203 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000204
205 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000207public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000208 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
209 const MCInstrInfo &MII)
210 : MCTargetAsmParser(), STI(sti), Parser(parser),
211 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000212 // Initialize the set of available features.
213 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000214 }
215
Jack Carterb4dbc172012-09-05 23:34:03 +0000216 MCAsmParser &getParser() const { return Parser; }
217 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
218
Rafael Espindola870c4e92012-01-11 03:56:41 +0000219};
220}
221
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000222namespace {
223
224/// MipsOperand - Instances of this class represent a parsed Mips machine
225/// instruction.
226class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000227
Jack Carter873c7242013-01-12 01:03:14 +0000228public:
229 enum RegisterKind {
230 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000231 Kind_GPR32,
232 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000233 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000234 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000235 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000236 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000237 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000238 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000239 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000240 Kind_ACC64DSP,
241 Kind_LO32DSP,
242 Kind_HI32DSP
Jack Carter873c7242013-01-12 01:03:14 +0000243 };
244
245private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000246 enum KindTy {
247 k_CondCode,
248 k_CoprocNum,
249 k_Immediate,
250 k_Memory,
251 k_PostIndexRegister,
252 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000253 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000254 k_Token
255 } Kind;
256
257 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000258
Eric Christopher8996c5d2013-03-15 00:42:55 +0000259 struct Token {
260 const char *Data;
261 unsigned Length;
262 };
263
264 struct RegOp {
265 unsigned RegNum;
266 RegisterKind Kind;
267 };
268
269 struct ImmOp {
270 const MCExpr *Val;
271 };
272
273 struct MemOp {
274 unsigned Base;
275 const MCExpr *Off;
276 };
277
Jack Carterb4dbc172012-09-05 23:34:03 +0000278 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000279 struct Token Tok;
280 struct RegOp Reg;
281 struct ImmOp Imm;
282 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000283 };
284
285 SMLoc StartLoc, EndLoc;
286
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000287public:
288 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000289 assert(N == 1 && "Invalid number of operands!");
290 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000291 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000292
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000293 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
294 assert(N == 1 && "Invalid number of operands!");
295 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
296 }
297
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000298 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000299 // Add as immediate when possible. Null MCExpr = 0.
300 if (Expr == 0)
301 Inst.addOperand(MCOperand::CreateImm(0));
302 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
303 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
304 else
305 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000306 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000307
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000308 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000309 assert(N == 1 && "Invalid number of operands!");
310 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000311 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000312 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000313
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000314 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000315 assert(N == 2 && "Invalid number of operands!");
316
317 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
318
319 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000320 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000321 }
322
323 bool isReg() const { return Kind == k_Register; }
324 bool isImm() const { return Kind == k_Immediate; }
325 bool isToken() const { return Kind == k_Token; }
326 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000327 bool isPtrReg() const { return Kind == k_PtrReg; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000328
329 StringRef getToken() const {
330 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000331 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000332 }
333
334 unsigned getReg() const {
335 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000336 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000337 }
338
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000339 unsigned getPtrReg() const {
340 assert((Kind == k_PtrReg) && "Invalid access!");
341 return Reg.RegNum;
342 }
343
Jack Carter873c7242013-01-12 01:03:14 +0000344 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000345 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000346 Reg.Kind = RegKind;
347 }
348
Jack Carterb4dbc172012-09-05 23:34:03 +0000349 const MCExpr *getImm() const {
350 assert((Kind == k_Immediate) && "Invalid access!");
351 return Imm.Val;
352 }
353
Jack Carterdc1e35d2012-09-06 20:00:02 +0000354 unsigned getMemBase() const {
355 assert((Kind == k_Memory) && "Invalid access!");
356 return Mem.Base;
357 }
358
359 const MCExpr *getMemOff() const {
360 assert((Kind == k_Memory) && "Invalid access!");
361 return Mem.Off;
362 }
363
Jack Carterb4dbc172012-09-05 23:34:03 +0000364 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
365 MipsOperand *Op = new MipsOperand(k_Token);
366 Op->Tok.Data = Str.data();
367 Op->Tok.Length = Str.size();
368 Op->StartLoc = S;
369 Op->EndLoc = S;
370 return Op;
371 }
372
373 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
374 MipsOperand *Op = new MipsOperand(k_Register);
375 Op->Reg.RegNum = RegNum;
376 Op->StartLoc = S;
377 Op->EndLoc = E;
378 return Op;
379 }
380
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000381 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
382 MipsOperand *Op = new MipsOperand(k_PtrReg);
383 Op->Reg.RegNum = RegNum;
384 Op->StartLoc = S;
385 Op->EndLoc = E;
386 return Op;
387 }
388
Jack Carterb4dbc172012-09-05 23:34:03 +0000389 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
390 MipsOperand *Op = new MipsOperand(k_Immediate);
391 Op->Imm.Val = Val;
392 Op->StartLoc = S;
393 Op->EndLoc = E;
394 return Op;
395 }
396
Jack Carterdc1e35d2012-09-06 20:00:02 +0000397 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
398 SMLoc S, SMLoc E) {
399 MipsOperand *Op = new MipsOperand(k_Memory);
400 Op->Mem.Base = Base;
401 Op->Mem.Off = Off;
402 Op->StartLoc = S;
403 Op->EndLoc = E;
404 return Op;
405 }
406
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000407 bool isGPR32Asm() const {
408 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000409 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000410 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000411 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
412 }
413
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000414 bool isGPR64Asm() const {
415 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000416 }
Jack Carter873c7242013-01-12 01:03:14 +0000417
418 bool isHWRegsAsm() const {
419 assert((Kind == k_Register) && "Invalid access!");
420 return Reg.Kind == Kind_HWRegs;
421 }
Jack Carter873c7242013-01-12 01:03:14 +0000422
Jack Carter873c7242013-01-12 01:03:14 +0000423 bool isCCRAsm() const {
424 assert((Kind == k_Register) && "Invalid access!");
425 return Reg.Kind == Kind_CCRRegs;
426 }
427
Vladimir Medic233dd512013-06-24 10:05:34 +0000428 bool isAFGR64Asm() const {
429 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
430 }
431
432 bool isFGR64Asm() const {
433 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
434 }
435
436 bool isFGR32Asm() const {
437 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
438 }
439
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000440 bool isFGRH32Asm() const {
441 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
442 }
443
Vladimir Medic643b3982013-07-30 10:12:14 +0000444 bool isFCCRegsAsm() const {
445 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
446 }
447
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000448 bool isACC64DSPAsm() const {
449 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000450 }
451
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000452 bool isLO32DSPAsm() const {
453 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
454 }
455
456 bool isHI32DSPAsm() const {
457 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
458 }
459
Jack Carterb4dbc172012-09-05 23:34:03 +0000460 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000461 SMLoc getStartLoc() const {
462 return StartLoc;
463 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000464 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000465 SMLoc getEndLoc() const {
466 return EndLoc;
467 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000468
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000469 virtual void print(raw_ostream &OS) const {
470 llvm_unreachable("unimplemented!");
471 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000472}; // class MipsOperand
473} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000474
Jack Carter9e65aa32013-03-22 00:05:30 +0000475namespace llvm {
476extern const MCInstrDesc MipsInsts[];
477}
478static const MCInstrDesc &getInstDesc(unsigned Opcode) {
479 return MipsInsts[Opcode];
480}
481
482bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000483 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000484 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
485 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000486 if (MCID.hasDelaySlot() && Options.isReorder()) {
487 // If this instruction has a delay slot and .set reorder is active,
488 // emit a NOP after it.
489 Instructions.push_back(Inst);
490 MCInst NopInst;
491 NopInst.setOpcode(Mips::SLL);
492 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
493 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
494 NopInst.addOperand(MCOperand::CreateImm(0));
495 Instructions.push_back(NopInst);
496 return false;
497 }
498
Jack Carter9e65aa32013-03-22 00:05:30 +0000499 if (MCID.mayLoad() || MCID.mayStore()) {
500 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000501 // reference or immediate we may have to expand instructions.
502 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000503 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000504 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
505 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000506 MCOperand &Op = Inst.getOperand(i);
507 if (Op.isImm()) {
508 int MemOffset = Op.getImm();
509 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000510 // Offset can't exceed 16bit value.
511 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000512 return false;
513 }
514 } else if (Op.isExpr()) {
515 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000516 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000517 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000518 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000519 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000520 // Expand symbol.
521 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000522 return false;
523 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000524 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000525 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000526 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000527 }
528 }
529 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000530 } // for
531 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000532
533 if (needsExpansion(Inst))
534 expandInstruction(Inst, IDLoc, Instructions);
535 else
536 Instructions.push_back(Inst);
537
538 return false;
539}
540
Jack Carter30a59822012-10-04 04:03:53 +0000541bool MipsAsmParser::needsExpansion(MCInst &Inst) {
542
Jack Carterd0bd6422013-04-18 00:41:53 +0000543 switch (Inst.getOpcode()) {
544 case Mips::LoadImm32Reg:
545 case Mips::LoadAddr32Imm:
546 case Mips::LoadAddr32Reg:
547 return true;
548 default:
549 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000550 }
551}
Jack Carter92995f12012-10-06 00:53:28 +0000552
Jack Carter30a59822012-10-04 04:03:53 +0000553void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000554 SmallVectorImpl<MCInst> &Instructions) {
555 switch (Inst.getOpcode()) {
556 case Mips::LoadImm32Reg:
557 return expandLoadImm(Inst, IDLoc, Instructions);
558 case Mips::LoadAddr32Imm:
559 return expandLoadAddressImm(Inst, IDLoc, Instructions);
560 case Mips::LoadAddr32Reg:
561 return expandLoadAddressReg(Inst, IDLoc, Instructions);
562 }
Jack Carter30a59822012-10-04 04:03:53 +0000563}
Jack Carter92995f12012-10-06 00:53:28 +0000564
Jack Carter30a59822012-10-04 04:03:53 +0000565void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000566 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000567 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000568 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000569 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000570 const MCOperand &RegOp = Inst.getOperand(0);
571 assert(RegOp.isReg() && "expected register operand kind");
572
573 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000574 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000575 if (0 <= ImmValue && ImmValue <= 65535) {
576 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000577 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000578 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000579 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000580 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000581 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000582 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000583 } else if (ImmValue < 0 && ImmValue >= -32768) {
584 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000585 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000586 tmpInst.setOpcode(Mips::ADDiu);
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);
591 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000592 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000593 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000594 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000595 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000596 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
597 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000598 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000599 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000600 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000601 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
602 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
603 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
604 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000605 Instructions.push_back(tmpInst);
606 }
607}
Jack Carter92995f12012-10-06 00:53:28 +0000608
Jack Carter543fdf82012-10-09 23:29:45 +0000609void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000610 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000611 MCInst tmpInst;
612 const MCOperand &ImmOp = Inst.getOperand(2);
613 assert(ImmOp.isImm() && "expected immediate operand kind");
614 const MCOperand &SrcRegOp = Inst.getOperand(1);
615 assert(SrcRegOp.isReg() && "expected register operand kind");
616 const MCOperand &DstRegOp = Inst.getOperand(0);
617 assert(DstRegOp.isReg() && "expected register operand kind");
618 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000619 if (-32768 <= ImmValue && ImmValue <= 65535) {
620 // For -32768 <= j <= 65535.
621 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000622 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000623 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
624 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
625 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
626 Instructions.push_back(tmpInst);
627 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000628 // For any other value of j that is representable as a 32-bit integer.
629 // la d,j(s) => lui d,hi16(j)
630 // ori d,d,lo16(j)
631 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000632 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000633 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
634 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
635 Instructions.push_back(tmpInst);
636 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000637 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000638 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
639 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
640 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
641 Instructions.push_back(tmpInst);
642 tmpInst.clear();
643 tmpInst.setOpcode(Mips::ADDu);
644 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
645 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
646 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
647 Instructions.push_back(tmpInst);
648 }
649}
650
651void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000652 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000653 MCInst tmpInst;
654 const MCOperand &ImmOp = Inst.getOperand(1);
655 assert(ImmOp.isImm() && "expected immediate operand kind");
656 const MCOperand &RegOp = Inst.getOperand(0);
657 assert(RegOp.isReg() && "expected register operand kind");
658 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000659 if (-32768 <= ImmValue && ImmValue <= 65535) {
660 // For -32768 <= j <= 65535.
661 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000662 tmpInst.setOpcode(Mips::ADDiu);
663 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000664 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000665 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
666 Instructions.push_back(tmpInst);
667 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000668 // For any other value of j that is representable as a 32-bit integer.
669 // la d,j => lui d,hi16(j)
670 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000671 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000672 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
673 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
674 Instructions.push_back(tmpInst);
675 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000676 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000677 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
678 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
679 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
680 Instructions.push_back(tmpInst);
681 }
682}
683
Jack Carter9e65aa32013-03-22 00:05:30 +0000684void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000685 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000686 const MCSymbolRefExpr *SR;
687 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000688 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000689 const MCExpr *ExprOffset;
690 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000691 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
692 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000693 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000694 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
695 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000696 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000697 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
698 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000699 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000700 if (isImmOpnd) {
701 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
702 ImmOffset = Inst.getOperand(2).getImm();
703 LoOffset = ImmOffset & 0x0000ffff;
704 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000705 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000706 if (LoOffset & 0x8000)
707 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000708 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000709 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000710 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000711 TempInst.setLoc(IDLoc);
712 // 1st instruction in expansion is LUi. For load instruction we can use
713 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000714 // but for stores we must use $at.
715 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000716 TempInst.setOpcode(Mips::LUi);
717 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
718 if (isImmOpnd)
719 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
720 else {
721 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
722 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000723 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
724 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
725 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000726 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000727 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000728 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000729 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000730 }
731 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000732 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000733 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000734 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000735 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000736 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000737 TempInst.setOpcode(Mips::ADDu);
738 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
739 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
740 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
741 Instructions.push_back(TempInst);
742 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000743 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000744 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000745 TempInst.setOpcode(Inst.getOpcode());
746 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
747 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
748 if (isImmOpnd)
749 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
750 else {
751 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000752 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
753 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
754 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000755 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000756 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000757 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000758 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000759 }
760 }
761 Instructions.push_back(TempInst);
762 TempInst.clear();
763}
764
Rafael Espindola870c4e92012-01-11 03:56:41 +0000765bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000766MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000767 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000768 MCStreamer &Out, unsigned &ErrorInfo,
769 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000770 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000771 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000772 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000773 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000774
775 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000776 default:
777 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000778 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000779 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000780 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000781 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000782 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000783 return false;
784 }
785 case Match_MissingFeature:
786 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
787 return true;
788 case Match_InvalidOperand: {
789 SMLoc ErrorLoc = IDLoc;
790 if (ErrorInfo != ~0U) {
791 if (ErrorInfo >= Operands.size())
792 return Error(IDLoc, "too few operands for instruction");
793
Jack Carterd0bd6422013-04-18 00:41:53 +0000794 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
795 if (ErrorLoc == SMLoc())
796 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000797 }
798
799 return Error(ErrorLoc, "invalid operand for instruction");
800 }
801 case Match_MnemonicFail:
802 return Error(IDLoc, "invalid instruction");
803 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000804 return true;
805}
806
Jack Carter1ac53222013-02-20 23:11:17 +0000807int MipsAsmParser::matchCPURegisterName(StringRef Name) {
808 int CC;
809
810 if (Name == "at")
811 return getATReg();
812
813 CC = StringSwitch<unsigned>(Name)
814 .Case("zero", 0)
815 .Case("a0", 4)
816 .Case("a1", 5)
817 .Case("a2", 6)
818 .Case("a3", 7)
819 .Case("v0", 2)
820 .Case("v1", 3)
821 .Case("s0", 16)
822 .Case("s1", 17)
823 .Case("s2", 18)
824 .Case("s3", 19)
825 .Case("s4", 20)
826 .Case("s5", 21)
827 .Case("s6", 22)
828 .Case("s7", 23)
829 .Case("k0", 26)
830 .Case("k1", 27)
831 .Case("sp", 29)
832 .Case("fp", 30)
833 .Case("gp", 28)
834 .Case("ra", 31)
835 .Case("t0", 8)
836 .Case("t1", 9)
837 .Case("t2", 10)
838 .Case("t3", 11)
839 .Case("t4", 12)
840 .Case("t5", 13)
841 .Case("t6", 14)
842 .Case("t7", 15)
843 .Case("t8", 24)
844 .Case("t9", 25)
845 .Default(-1);
846
Jack Carterd0bd6422013-04-18 00:41:53 +0000847 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000848 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
849 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000850 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000851 CC += 4;
852
853 if (CC == -1 && isMips64())
854 CC = StringSwitch<unsigned>(Name)
855 .Case("a4", 8)
856 .Case("a5", 9)
857 .Case("a6", 10)
858 .Case("a7", 11)
859 .Case("kt0", 26)
860 .Case("kt1", 27)
861 .Case("s8", 30)
862 .Default(-1);
863
864 return CC;
865}
Jack Carterd0bd6422013-04-18 00:41:53 +0000866
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000867int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000868
Jack Cartera63b16a2012-09-07 00:23:42 +0000869 if (Name[0] == 'f') {
870 StringRef NumString = Name.substr(1);
871 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000872 if (NumString.getAsInteger(10, IntVal))
873 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000874 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000875 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000876 return IntVal;
877 }
878 return -1;
879}
Jack Cartera63b16a2012-09-07 00:23:42 +0000880
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000881int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
882
883 if (Name.startswith("fcc")) {
884 StringRef NumString = Name.substr(3);
885 unsigned IntVal;
886 if (NumString.getAsInteger(10, IntVal))
887 return -1; // This is not an integer.
888 if (IntVal > 7) // There are only 8 fcc registers.
889 return -1;
890 return IntVal;
891 }
892 return -1;
893}
894
895int MipsAsmParser::matchACRegisterName(StringRef Name) {
896
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000897 if (Name.startswith("ac")) {
898 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000899 unsigned IntVal;
900 if (NumString.getAsInteger(10, IntVal))
901 return -1; // This is not an integer.
902 if (IntVal > 3) // There are only 3 acc registers.
903 return -1;
904 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000905 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000906 return -1;
907}
Jack Carterd0bd6422013-04-18 00:41:53 +0000908
Vladimir Medic8cd17102013-06-20 11:21:49 +0000909int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
910
Vladimir Medic8cd17102013-06-20 11:21:49 +0000911 int CC;
912 CC = matchCPURegisterName(Name);
913 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000914 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
915 : Mips::GPR32RegClassID);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000916 CC= matchFPURegisterName(Name);
917 //TODO: decide about fpu register class
918 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
919 : Mips::FGR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000920}
921
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000922int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000923
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000924 switch (RegKind) {
925 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
926 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
927 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
928 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000929 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000930 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
931 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
932 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
933 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
934 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
935 default :return -1;
936 }
Jack Cartera63b16a2012-09-07 00:23:42 +0000937
Jack Cartera63b16a2012-09-07 00:23:42 +0000938}
Jack Carterb4dbc172012-09-05 23:34:03 +0000939
Jack Carter0b744b32012-10-04 02:29:46 +0000940bool MipsAssemblerOptions::setATReg(unsigned Reg) {
941 if (Reg > 31)
942 return false;
943
944 aTReg = Reg;
945 return true;
946}
947
Jack Carter1ac53222013-02-20 23:11:17 +0000948int MipsAsmParser::getATReg() {
949 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +0000950}
951
Jack Carterd0bd6422013-04-18 00:41:53 +0000952unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +0000953 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +0000954}
955
Jack Carter873c7242013-01-12 01:03:14 +0000956int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000957 if (RegNum >
958 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +0000959 return -1;
960
Jack Carter873c7242013-01-12 01:03:14 +0000961 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +0000962}
963
Jack Carter873c7242013-01-12 01:03:14 +0000964int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000965 const AsmToken &Tok = Parser.getTok();
966 int RegNum = -1;
967
968 if (Tok.is(AsmToken::Identifier)) {
969 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +0000970 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000971 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +0000972 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000973 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +0000974 return RegNum;
975}
976
Jack Carterd0bd6422013-04-18 00:41:53 +0000977bool MipsAsmParser::tryParseRegisterOperand(
978 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000979
980 SMLoc S = Parser.getTok().getLoc();
981 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +0000982
Jack Carter873c7242013-01-12 01:03:14 +0000983 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000984 if (RegNo == -1)
985 return true;
986
Jack Carter873c7242013-01-12 01:03:14 +0000987 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +0000988 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +0000989 Parser.Lex(); // Eat register token.
990 return false;
991}
992
993bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
994 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +0000995 // Check if the current operand has a custom associated parser, if so, try to
996 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +0000997 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
998 if (ResTy == MatchOperand_Success)
999 return false;
1000 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1001 // there was a match, but an error occurred, in which case, just return that
1002 // the operand parsing failed.
1003 if (ResTy == MatchOperand_ParseFail)
1004 return true;
1005
1006 switch (getLexer().getKind()) {
1007 default:
1008 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1009 return true;
1010 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001011 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001012 SMLoc S = Parser.getTok().getLoc();
1013 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001014 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001015 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001016 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001017 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001018 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001019 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001020 if (getLexer().isNot(AsmToken::Dollar))
1021 return true;
1022
Jack Carterd0bd6422013-04-18 00:41:53 +00001023 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001024 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001025 return true;
1026
1027 if (!getLexer().is(AsmToken::RParen))
1028 return true;
1029
1030 S = Parser.getTok().getLoc();
1031 Operands.push_back(MipsOperand::CreateToken(")", S));
1032 Parser.Lex();
1033 }
1034 return false;
1035 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001036 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001037 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001038 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001039 return true;
1040
Jack Carter873c7242013-01-12 01:03:14 +00001041 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001042
Benjamin Kramerfa530572012-09-07 09:47:42 +00001043 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001044
Jack Carterd0bd6422013-04-18 00:41:53 +00001045 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001046 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001047 getContext());
1048
1049 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1050 return false;
1051 }
1052 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001053 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001054 // we need to assigne the propper RegisterKind.
1055 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1056 return false;
1057 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001058 case AsmToken::LParen:
1059 case AsmToken::Minus:
1060 case AsmToken::Plus:
1061 case AsmToken::Integer:
1062 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001063 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001064 const MCExpr *IdVal;
1065 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001066 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001067 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001068 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001069 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1070 return false;
1071 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001072 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001073 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001074 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001075 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001076 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001077 return true;
1078
Jack Carter873c7242013-01-12 01:03:14 +00001079 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1080
Jack Carterdc1e35d2012-09-06 20:00:02 +00001081 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1082 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001083 } // case AsmToken::Percent
1084 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001085 return true;
1086}
1087
Jack Carterb5cf5902013-04-17 00:18:04 +00001088const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1089 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001090 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001091 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001092 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001093 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001094 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001095 short Val = MCE->getValue();
1096 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001097 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001098 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001099 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001100 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001101 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001102 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001103 if (LoSign)
1104 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001105 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001106 } else {
1107 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001108 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001109 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001110 }
1111
Jack Carterb5cf5902013-04-17 00:18:04 +00001112 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001113 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001114 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001115 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001116 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001117 return Res;
1118 }
1119
1120 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001121 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1122 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001123 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1124 return Res;
1125 }
1126
1127 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001128 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1129 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1130 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001131 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001132 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001133 return Expr;
1134}
1135
1136bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1137
1138 switch (Expr->getKind()) {
1139 case MCExpr::Constant:
1140 return true;
1141 case MCExpr::SymbolRef:
1142 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1143 case MCExpr::Binary:
1144 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1145 if (!isEvaluated(BE->getLHS()))
1146 return false;
1147 return isEvaluated(BE->getRHS());
1148 }
1149 case MCExpr::Unary:
1150 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1151 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001152 return false;
1153 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001154 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001155}
Jack Carterd0bd6422013-04-18 00:41:53 +00001156
Jack Carterb5cf5902013-04-17 00:18:04 +00001157bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001158 Parser.Lex(); // Eat the % token.
1159 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001160 if (Tok.isNot(AsmToken::Identifier))
1161 return true;
1162
1163 std::string Str = Tok.getIdentifier().str();
1164
Jack Carterd0bd6422013-04-18 00:41:53 +00001165 Parser.Lex(); // Eat the identifier.
1166 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001167 const MCExpr *IdVal;
1168 SMLoc EndLoc;
1169
1170 if (getLexer().getKind() == AsmToken::LParen) {
1171 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001172 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001173 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001174 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001175 const AsmToken &nextTok = Parser.getTok();
1176 if (nextTok.isNot(AsmToken::Identifier))
1177 return true;
1178 Str += "(%";
1179 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001180 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001181 if (getLexer().getKind() != AsmToken::LParen)
1182 return true;
1183 } else
1184 break;
1185 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001186 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001187 return true;
1188
1189 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001190 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001191
1192 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001193 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001194
Jack Carterd0bd6422013-04-18 00:41:53 +00001195 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001196 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001197}
1198
Jack Carterb4dbc172012-09-05 23:34:03 +00001199bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1200 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001201 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001202 RegNo = tryParseRegister(isMips64());
1203 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001204 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001205}
1206
Jack Carterb5cf5902013-04-17 00:18:04 +00001207bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001208 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001209 bool Result = true;
1210
1211 while (getLexer().getKind() == AsmToken::LParen)
1212 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001213
Jack Carterd0bd6422013-04-18 00:41:53 +00001214 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001215 default:
1216 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001217 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001218 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001219 case AsmToken::Integer:
1220 case AsmToken::Minus:
1221 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001222 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001223 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001224 else
1225 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001226 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001227 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001228 break;
Jack Carter873c7242013-01-12 01:03:14 +00001229 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001230 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001231 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001232 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001233}
1234
Jack Carterb4dbc172012-09-05 23:34:03 +00001235MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001236 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001237
1238 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001239 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001240 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001241 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001242 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001243 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001244
Jack Carterb5cf5902013-04-17 00:18:04 +00001245 if (getLexer().getKind() == AsmToken::LParen) {
1246 Parser.Lex();
1247 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001248 }
1249
Jack Carterb5cf5902013-04-17 00:18:04 +00001250 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001251 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001252 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001253
Jack Carterd0bd6422013-04-18 00:41:53 +00001254 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001255 if (Tok.isNot(AsmToken::LParen)) {
1256 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1257 if (Mnemonic->getToken() == "la") {
1258 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001259 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001260 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1261 return MatchOperand_Success;
1262 }
1263 if (Tok.is(AsmToken::EndOfStatement)) {
1264 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001265 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001266
Jack Carterd0bd6422013-04-18 00:41:53 +00001267 // Zero register assumed, add a memory operand with ZERO as its base.
1268 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1269 : Mips::ZERO,
1270 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001271 return MatchOperand_Success;
1272 }
1273 Error(Parser.getTok().getLoc(), "'(' expected");
1274 return MatchOperand_ParseFail;
1275 }
1276
Jack Carterd0bd6422013-04-18 00:41:53 +00001277 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001278 }
1279
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001280 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1281 (int) MipsOperand::Kind_GPR32);
1282 if (Res != MatchOperand_Success)
1283 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001284
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001285 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001286 Error(Parser.getTok().getLoc(), "')' expected");
1287 return MatchOperand_ParseFail;
1288 }
1289
Jack Carter873c7242013-01-12 01:03:14 +00001290 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1291
Jack Carterd0bd6422013-04-18 00:41:53 +00001292 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001293
1294 if (IdVal == 0)
1295 IdVal = MCConstantExpr::Create(0, getContext());
1296
Jack Carterd0bd6422013-04-18 00:41:53 +00001297 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001298 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1299 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001300 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001301 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001302 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001303 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1304 int64_t Imm;
1305 if (IdVal->EvaluateAsAbsolute(Imm))
1306 IdVal = MCConstantExpr::Create(Imm, getContext());
1307 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1308 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1309 getContext());
1310 }
1311
Jack Carterdc1e35d2012-09-06 20:00:02 +00001312 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1313 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001314 return MatchOperand_Success;
1315}
1316
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001317bool
1318MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1319 int RegKind) {
1320 // If the first token is not '$' we have an error.
1321 if (Parser.getTok().isNot(AsmToken::Dollar))
1322 return false;
1323
1324 SMLoc S = Parser.getTok().getLoc();
1325 Parser.Lex();
1326 AsmToken::TokenKind TkKind = getLexer().getKind();
1327 int Reg;
1328
1329 if (TkKind == AsmToken::Integer) {
1330 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1331 regKindToRegClass(RegKind));
1332 if (Reg == -1)
1333 return false;
1334 } else if (TkKind == AsmToken::Identifier) {
1335 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1336 return false;
1337 Reg = getReg(regKindToRegClass(RegKind), Reg);
1338 } else {
1339 return false;
1340 }
1341
1342 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1343 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1344 Operands.push_back(Op);
1345 Parser.Lex();
1346 return true;
1347}
1348
1349MipsAsmParser::OperandMatchResultTy
1350MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1351 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1352 MipsOperand::Kind_GPR32;
1353
1354 // Parse index register.
1355 if (!parsePtrReg(Operands, RegKind))
1356 return MatchOperand_NoMatch;
1357
1358 // Parse '('.
1359 if (Parser.getTok().isNot(AsmToken::LParen))
1360 return MatchOperand_NoMatch;
1361
1362 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1363 Parser.Lex();
1364
1365 // Parse base register.
1366 if (!parsePtrReg(Operands, RegKind))
1367 return MatchOperand_NoMatch;
1368
1369 // Parse ')'.
1370 if (Parser.getTok().isNot(AsmToken::RParen))
1371 return MatchOperand_NoMatch;
1372
1373 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1374 Parser.Lex();
1375
1376 return MatchOperand_Success;
1377}
1378
Jack Carter873c7242013-01-12 01:03:14 +00001379MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001380MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1381 int RegKind) {
1382 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001383 if (getLexer().getKind() == AsmToken::Identifier
1384 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001385 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001386 return MatchOperand_Success;
1387 return MatchOperand_NoMatch;
1388 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001389 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001390 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001391 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001392 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001393 if (!hasConsumedDollar) {
1394 Parser.Lex(); // Eat the '$'
1395 hasConsumedDollar = true;
1396 }
1397 if (getLexer().getKind() == AsmToken::Identifier) {
1398 int RegNum = -1;
1399 std::string RegName = Parser.getTok().getString().lower();
1400 // Match register by name
1401 switch (RegKind) {
1402 case MipsOperand::Kind_GPR32:
1403 case MipsOperand::Kind_GPR64:
1404 RegNum = matchCPURegisterName(RegName);
1405 break;
1406 case MipsOperand::Kind_AFGR64Regs:
1407 case MipsOperand::Kind_FGR64Regs:
1408 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001409 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001410 RegNum = matchFPURegisterName(RegName);
1411 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1412 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001413 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1414 && !isFP64())
1415 if (RegNum != -1 && RegNum %2 != 0)
1416 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001417 break;
1418 case MipsOperand::Kind_FCCRegs:
1419 RegNum = matchFCCRegisterName(RegName);
1420 break;
1421 case MipsOperand::Kind_ACC64DSP:
1422 RegNum = matchACRegisterName(RegName);
1423 break;
1424 default: break; // No match, value is set to -1.
1425 }
1426 // No match found, return _NoMatch to give a chance to other round.
1427 if (RegNum < 0)
1428 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001429
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001430 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1431 if (RegVal == -1)
1432 return MatchOperand_NoMatch;
1433
1434 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1435 Parser.getTok().getLoc());
1436 Op->setRegKind(Kind);
1437 Operands.push_back(Op);
1438 hasConsumedDollar = false;
1439 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001440 return MatchOperand_Success;
1441 } else if (getLexer().getKind() == AsmToken::Integer) {
1442 unsigned RegNum = Parser.getTok().getIntVal();
1443 if (Kind == MipsOperand::Kind_HWRegs) {
1444 if (RegNum != 29)
1445 return MatchOperand_NoMatch;
1446 // Only hwreg 29 is supported, found at index 0.
1447 RegNum = 0;
1448 }
1449 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1450 if (Reg == -1)
1451 return MatchOperand_NoMatch;
1452 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1453 Op->setRegKind(Kind);
1454 Operands.push_back(Op);
1455 hasConsumedDollar = false;
1456 Parser.Lex(); // Eat the register number.
1457 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001458 && (getLexer().is(AsmToken::LParen))) {
1459 // Check if it is indexed addressing operand.
1460 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1461 Parser.Lex(); // Eat the parenthesis.
1462 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1463 return MatchOperand_NoMatch;
1464 if (getLexer().isNot(AsmToken::RParen))
1465 return MatchOperand_NoMatch;
1466 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1467 Parser.Lex();
1468 }
Jack Carter873c7242013-01-12 01:03:14 +00001469 return MatchOperand_Success;
1470 }
1471 return MatchOperand_NoMatch;
1472}
Vladimir Medic64828a12013-07-16 10:07:14 +00001473
Vladimir Medic8cd17102013-06-20 11:21:49 +00001474MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001475MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001476
1477 if (!isMips64())
1478 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001479 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001480}
1481
1482MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001483MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1484 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001485}
Jack Carter873c7242013-01-12 01:03:14 +00001486
Vladimir Medic233dd512013-06-24 10:05:34 +00001487MipsAsmParser::OperandMatchResultTy
1488MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1489
1490 if (isFP64())
1491 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001492 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1493}
1494
1495MipsAsmParser::OperandMatchResultTy
1496MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1497 if (!isFP64())
1498 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001499 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1500}
1501
1502MipsAsmParser::OperandMatchResultTy
1503MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001504 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1505}
1506
Vladimir Medic643b3982013-07-30 10:12:14 +00001507MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001508MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1509 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1510}
1511
1512MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001513MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001514 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001515}
1516
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001517MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001518MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001519 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001520}
1521
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001522MipsAsmParser::OperandMatchResultTy
1523MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1524 // If the first token is not '$' we have an error.
1525 if (Parser.getTok().isNot(AsmToken::Dollar))
1526 return MatchOperand_NoMatch;
1527
1528 SMLoc S = Parser.getTok().getLoc();
1529 Parser.Lex(); // Eat the '$'
1530
1531 const AsmToken &Tok = Parser.getTok(); // Get next token.
1532
1533 if (Tok.isNot(AsmToken::Identifier))
1534 return MatchOperand_NoMatch;
1535
1536 if (!Tok.getIdentifier().startswith("ac"))
1537 return MatchOperand_NoMatch;
1538
1539 StringRef NumString = Tok.getIdentifier().substr(2);
1540
1541 unsigned IntVal;
1542 if (NumString.getAsInteger(10, IntVal))
1543 return MatchOperand_NoMatch;
1544
1545 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1546
1547 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1548 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1549 Operands.push_back(Op);
1550
1551 Parser.Lex(); // Eat the register number.
1552 return MatchOperand_Success;
1553}
1554
1555MipsAsmParser::OperandMatchResultTy
1556MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1557 // If the first token is not '$' we have an error.
1558 if (Parser.getTok().isNot(AsmToken::Dollar))
1559 return MatchOperand_NoMatch;
1560
1561 SMLoc S = Parser.getTok().getLoc();
1562 Parser.Lex(); // Eat the '$'
1563
1564 const AsmToken &Tok = Parser.getTok(); // Get next token.
1565
1566 if (Tok.isNot(AsmToken::Identifier))
1567 return MatchOperand_NoMatch;
1568
1569 if (!Tok.getIdentifier().startswith("ac"))
1570 return MatchOperand_NoMatch;
1571
1572 StringRef NumString = Tok.getIdentifier().substr(2);
1573
1574 unsigned IntVal;
1575 if (NumString.getAsInteger(10, IntVal))
1576 return MatchOperand_NoMatch;
1577
1578 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1579
1580 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1581 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1582 Operands.push_back(Op);
1583
1584 Parser.Lex(); // Eat the register number.
1585 return MatchOperand_Success;
1586}
1587
Jack Carterd0bd6422013-04-18 00:41:53 +00001588bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001589 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001590
1591 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1592 if (Sym) {
1593 SMLoc S = Parser.getTok().getLoc();
1594 const MCExpr *Expr;
1595 if (Sym->isVariable())
1596 Expr = Sym->getVariableValue();
1597 else
1598 return false;
1599 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001600 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001601 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1602 const StringRef DefSymbol = Ref->getSymbol().getName();
1603 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001604 int RegNum = -1;
1605 APInt IntVal(32, -1);
1606 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1607 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001608 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001609 ? Mips::GPR64RegClassID
1610 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001611 else {
1612 // Lookup for the register with the corresponding name.
1613 switch (Kind) {
1614 case MipsOperand::Kind_AFGR64Regs:
1615 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001616 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001617 break;
1618 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001619 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001620 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001621 case MipsOperand::Kind_GPR64:
1622 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001623 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001624 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001625 break;
1626 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001627 if (RegNum > -1)
1628 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001629 }
Jack Carterd76b2372013-03-21 21:44:16 +00001630 if (RegNum > -1) {
1631 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001632 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1633 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001634 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001635 Operands.push_back(op);
1636 return true;
1637 }
1638 }
1639 } else if (Expr->getKind() == MCExpr::Constant) {
1640 Parser.Lex();
1641 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001642 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001643 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001644 Operands.push_back(op);
1645 return true;
1646 }
1647 }
1648 return false;
1649}
Jack Carterd0bd6422013-04-18 00:41:53 +00001650
Jack Carter873c7242013-01-12 01:03:14 +00001651MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001652MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001653 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001654}
1655
1656MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001657MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001658 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001659}
1660
Jack Carterdc1e35d2012-09-06 20:00:02 +00001661MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1662
1663 MCSymbolRefExpr::VariantKind VK
1664 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1665 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1666 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1667 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1668 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1669 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1670 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1671 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1672 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1673 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1674 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1675 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1676 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1677 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1678 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1679 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1680 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1681 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1682 .Default(MCSymbolRefExpr::VK_None);
1683
1684 return VK;
1685}
Jack Cartera63b16a2012-09-07 00:23:42 +00001686
Rafael Espindola870c4e92012-01-11 03:56:41 +00001687bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001688ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001689 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001690 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001691 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001692 Parser.eatToEndOfStatement();
1693 return Error(NameLoc, "Unknown instruction");
1694 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001695 // First operand in MCInst is instruction mnemonic.
1696 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001697
1698 // Read the remaining operands.
1699 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1700 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001701 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001702 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001703 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001704 return Error(Loc, "unexpected token in argument list");
1705 }
1706
Jack Carterd0bd6422013-04-18 00:41:53 +00001707 while (getLexer().is(AsmToken::Comma)) {
1708 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001709 // Parse and remember the operand.
1710 if (ParseOperand(Operands, Name)) {
1711 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001712 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001713 return Error(Loc, "unexpected token in argument list");
1714 }
1715 }
1716 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001717 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1718 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001719 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001720 return Error(Loc, "unexpected token in argument list");
1721 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001722 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001723 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001724}
1725
Jack Carter0b744b32012-10-04 02:29:46 +00001726bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001727 SMLoc Loc = getLexer().getLoc();
1728 Parser.eatToEndOfStatement();
1729 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001730}
1731
1732bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001733 // Line should look like: ".set noat".
1734 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001735 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001736 // eat noat
1737 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001738 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001739 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1740 reportParseError("unexpected token in statement");
1741 return false;
1742 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001743 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001744 return false;
1745}
Jack Carterd0bd6422013-04-18 00:41:53 +00001746
Jack Carter0b744b32012-10-04 02:29:46 +00001747bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001748 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001749 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001750 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001751 getParser().Lex();
1752 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001753 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001754 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001755 return false;
1756 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001757 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001758 if (getLexer().isNot(AsmToken::Dollar)) {
1759 reportParseError("unexpected token in statement");
1760 return false;
1761 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001762 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001763 const AsmToken &Reg = Parser.getTok();
1764 if (Reg.is(AsmToken::Identifier)) {
1765 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1766 } else if (Reg.is(AsmToken::Integer)) {
1767 AtRegNo = Reg.getIntVal();
1768 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001769 reportParseError("unexpected token in statement");
1770 return false;
1771 }
Jack Carter1ac53222013-02-20 23:11:17 +00001772
Jack Carterd0bd6422013-04-18 00:41:53 +00001773 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001774 reportParseError("unexpected token in statement");
1775 return false;
1776 }
1777
1778 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001779 reportParseError("unexpected token in statement");
1780 return false;
1781 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001782 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001783
1784 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1785 reportParseError("unexpected token in statement");
1786 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001787 }
1788 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001789 return false;
1790 } else {
1791 reportParseError("unexpected token in statement");
1792 return false;
1793 }
1794}
1795
1796bool MipsAsmParser::parseSetReorderDirective() {
1797 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001798 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001799 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1800 reportParseError("unexpected token in statement");
1801 return false;
1802 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001803 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001804 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001805 return false;
1806}
1807
1808bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001809 Parser.Lex();
1810 // If this is not the end of the statement, report an error.
1811 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1812 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001813 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001814 }
1815 Options.setNoreorder();
1816 Parser.Lex(); // Consume the EndOfStatement.
1817 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001818}
1819
1820bool MipsAsmParser::parseSetMacroDirective() {
1821 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001822 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001823 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1824 reportParseError("unexpected token in statement");
1825 return false;
1826 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001827 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001828 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001829 return false;
1830}
1831
1832bool MipsAsmParser::parseSetNoMacroDirective() {
1833 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001834 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001835 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1836 reportParseError("`noreorder' must be set before `nomacro'");
1837 return false;
1838 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001839 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00001840 reportParseError("`noreorder' must be set before `nomacro'");
1841 return false;
1842 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001843 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001844 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001845 return false;
1846}
Jack Carterd76b2372013-03-21 21:44:16 +00001847
1848bool MipsAsmParser::parseSetAssignment() {
1849 StringRef Name;
1850 const MCExpr *Value;
1851
1852 if (Parser.parseIdentifier(Name))
1853 reportParseError("expected identifier after .set");
1854
1855 if (getLexer().isNot(AsmToken::Comma))
1856 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00001857 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00001858
Jack Carter02593002013-05-28 22:21:05 +00001859 if (getLexer().is(AsmToken::Dollar)) {
1860 MCSymbol *Symbol;
1861 SMLoc DollarLoc = getLexer().getLoc();
1862 // Consume the dollar sign, and check for a following identifier.
1863 Parser.Lex();
1864 // We have a '$' followed by something, make sure they are adjacent.
1865 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1866 return true;
1867 StringRef Res = StringRef(DollarLoc.getPointer(),
1868 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1869 Symbol = getContext().GetOrCreateSymbol(Res);
1870 Parser.Lex();
1871 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1872 getContext());
1873 } else if (Parser.parseExpression(Value))
1874 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00001875
Jack Carterd0bd6422013-04-18 00:41:53 +00001876 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00001877 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00001878 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00001879 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00001880 Sym = getContext().GetOrCreateSymbol(Name);
1881 Sym->setVariableValue(Value);
1882
1883 return false;
1884}
Jack Carterd0bd6422013-04-18 00:41:53 +00001885
Jack Carter0b744b32012-10-04 02:29:46 +00001886bool MipsAsmParser::parseDirectiveSet() {
1887
Jack Carterd0bd6422013-04-18 00:41:53 +00001888 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00001889 const AsmToken &Tok = Parser.getTok();
1890
1891 if (Tok.getString() == "noat") {
1892 return parseSetNoAtDirective();
1893 } else if (Tok.getString() == "at") {
1894 return parseSetAtDirective();
1895 } else if (Tok.getString() == "reorder") {
1896 return parseSetReorderDirective();
1897 } else if (Tok.getString() == "noreorder") {
1898 return parseSetNoReorderDirective();
1899 } else if (Tok.getString() == "macro") {
1900 return parseSetMacroDirective();
1901 } else if (Tok.getString() == "nomacro") {
1902 return parseSetNoMacroDirective();
1903 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001904 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001905 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001906 return false;
1907 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001908 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001909 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00001910 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001911 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001912 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00001913 parseSetAssignment();
1914 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001915 }
Jack Carter07c818d2013-01-25 01:31:34 +00001916
Jack Carter0b744b32012-10-04 02:29:46 +00001917 return true;
1918}
1919
Jack Carter07c818d2013-01-25 01:31:34 +00001920/// parseDirectiveWord
1921/// ::= .word [ expression (, expression)* ]
1922bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1923 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1924 for (;;) {
1925 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001926 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00001927 return true;
1928
1929 getParser().getStreamer().EmitValue(Value, Size);
1930
1931 if (getLexer().is(AsmToken::EndOfStatement))
1932 break;
1933
1934 // FIXME: Improve diagnostic.
1935 if (getLexer().isNot(AsmToken::Comma))
1936 return Error(L, "unexpected token in directive");
1937 Parser.Lex();
1938 }
1939 }
1940
1941 Parser.Lex();
1942 return false;
1943}
1944
Jack Carter0b744b32012-10-04 02:29:46 +00001945bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00001946
Jack Carter07c818d2013-01-25 01:31:34 +00001947 StringRef IDVal = DirectiveID.getString();
1948
Jack Carterd0bd6422013-04-18 00:41:53 +00001949 if (IDVal == ".ent") {
1950 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001951 Parser.Lex();
1952 return false;
1953 }
1954
Jack Carter07c818d2013-01-25 01:31:34 +00001955 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001956 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00001957 Parser.Lex();
1958 return false;
1959 }
1960
Jack Carter07c818d2013-01-25 01:31:34 +00001961 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001962 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001963 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001964 return false;
1965 }
1966
Jack Carter07c818d2013-01-25 01:31:34 +00001967 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00001968 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00001969 }
1970
Jack Carter07c818d2013-01-25 01:31:34 +00001971 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001972 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001973 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001974 return false;
1975 }
1976
Jack Carter07c818d2013-01-25 01:31:34 +00001977 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001978 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001979 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001980 return false;
1981 }
1982
Jack Carter07c818d2013-01-25 01:31:34 +00001983 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00001984 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001985 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00001986 return false;
1987 }
1988
Jack Carter07c818d2013-01-25 01:31:34 +00001989 if (IDVal == ".word") {
1990 parseDirectiveWord(4, DirectiveID.getLoc());
1991 return false;
1992 }
1993
Rafael Espindola870c4e92012-01-11 03:56:41 +00001994 return true;
1995}
1996
Rafael Espindola870c4e92012-01-11 03:56:41 +00001997extern "C" void LLVMInitializeMipsAsmParser() {
1998 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1999 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2000 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2001 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2002}
Jack Carterb4dbc172012-09-05 23:34:03 +00002003
2004#define GET_REGISTER_MATCHER
2005#define GET_MATCHER_IMPLEMENTATION
2006#include "MipsGenAsmMatcher.inc"