blob: 1f39f48259c9ec9859b8cb92fb76970664bcbe73 [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 Carter5dc8ac92013-09-25 23:50:44 +000085 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
86 int RegKind);
87
88 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000089 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
90
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000091 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
92
93 MipsAsmParser::OperandMatchResultTy
94 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
95
Jack Carter873c7242013-01-12 01:03:14 +000096 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000097 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000098
99 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000100 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000101
102 MipsAsmParser::OperandMatchResultTy
103 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
104
105 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +0000106 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000107
Vladimir Medic233dd512013-06-24 10:05:34 +0000108 MipsAsmParser::OperandMatchResultTy
109 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
110
111 MipsAsmParser::OperandMatchResultTy
112 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
113
114 MipsAsmParser::OperandMatchResultTy
115 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
116
Vladimir Medic643b3982013-07-30 10:12:14 +0000117 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000118 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
119
120 MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +0000121 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
122
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000123 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000124 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000125
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000126 MipsAsmParser::OperandMatchResultTy
127 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
128
129 MipsAsmParser::OperandMatchResultTy
130 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
131
Vladimir Medic05bcde62013-09-16 10:29:42 +0000132 MipsAsmParser::OperandMatchResultTy
133 parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
134
Jack Carter5dc8ac92013-09-25 23:50:44 +0000135 MipsAsmParser::OperandMatchResultTy
136 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
137
138 MipsAsmParser::OperandMatchResultTy
139 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
140
141 MipsAsmParser::OperandMatchResultTy
142 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
143
144 MipsAsmParser::OperandMatchResultTy
145 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
146
Vladimir Medic2b953d02013-10-01 09:48:56 +0000147 MipsAsmParser::OperandMatchResultTy
148 parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
149
Jack Carterd76b2372013-03-21 21:44:16 +0000150 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000151 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000152
Jack Carterb4dbc172012-09-05 23:34:03 +0000153 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
154 StringRef Mnemonic);
155
Jack Carter873c7242013-01-12 01:03:14 +0000156 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000157
158 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000159 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000160
Jack Carter30a59822012-10-04 04:03:53 +0000161 bool needsExpansion(MCInst &Inst);
162
163 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000164 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000165 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000166 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000167 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
168 SmallVectorImpl<MCInst> &Instructions);
169 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000171 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
172 SmallVectorImpl<MCInst> &Instructions,
173 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000174 bool reportParseError(StringRef ErrorMsg);
175
Jack Carterb5cf5902013-04-17 00:18:04 +0000176 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000177 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000178
Jack Carterb5cf5902013-04-17 00:18:04 +0000179 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
180
181 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000182 bool parseDirectiveSet();
Rafael Espindolaac4ad252013-10-05 16:42:21 +0000183 bool parseDirectiveMipsHackStocg();
184 bool parseDirectiveMipsHackELFFlags();
Jack Carter0b744b32012-10-04 02:29:46 +0000185
186 bool parseSetAtDirective();
187 bool parseSetNoAtDirective();
188 bool parseSetMacroDirective();
189 bool parseSetNoMacroDirective();
190 bool parseSetReorderDirective();
191 bool parseSetNoReorderDirective();
192
Jack Carterd76b2372013-03-21 21:44:16 +0000193 bool parseSetAssignment();
194
Jack Carter07c818d2013-01-25 01:31:34 +0000195 bool parseDirectiveWord(unsigned Size, SMLoc L);
196
Jack Carterdc1e35d2012-09-06 20:00:02 +0000197 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000198
Jack Carterb4dbc172012-09-05 23:34:03 +0000199 bool isMips64() const {
200 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
201 }
202
Jack Cartera63b16a2012-09-07 00:23:42 +0000203 bool isFP64() const {
204 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
205 }
206
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000207 bool isN64() const {
208 return STI.getFeatureBits() & Mips::FeatureN64;
209 }
210
Jack Carter873c7242013-01-12 01:03:14 +0000211 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000212
Jack Carter1ac53222013-02-20 23:11:17 +0000213 int matchCPURegisterName(StringRef Symbol);
214
Jack Carter873c7242013-01-12 01:03:14 +0000215 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000216
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000217 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000218
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000219 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000220
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000221 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000222
Jack Carter5dc8ac92013-09-25 23:50:44 +0000223 int matchMSA128RegisterName(StringRef Name);
224
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000225 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000226
Jack Carterd0bd6422013-04-18 00:41:53 +0000227 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000228
Jack Carter1ac53222013-02-20 23:11:17 +0000229 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000230
231 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
232 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000233public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000234 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
235 const MCInstrInfo &MII)
236 : MCTargetAsmParser(), STI(sti), Parser(parser),
237 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000238 // Initialize the set of available features.
239 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000240 }
241
Jack Carterb4dbc172012-09-05 23:34:03 +0000242 MCAsmParser &getParser() const { return Parser; }
243 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
244
Rafael Espindola870c4e92012-01-11 03:56:41 +0000245};
246}
247
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000248namespace {
249
250/// MipsOperand - Instances of this class represent a parsed Mips machine
251/// instruction.
252class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000253
Jack Carter873c7242013-01-12 01:03:14 +0000254public:
255 enum RegisterKind {
256 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000257 Kind_GPR32,
258 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000259 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000260 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000261 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000262 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000263 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000264 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000265 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000266 Kind_ACC64DSP,
267 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000268 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000269 Kind_COP2,
270 Kind_MSA128BRegs,
271 Kind_MSA128HRegs,
272 Kind_MSA128WRegs,
273 Kind_MSA128DRegs
Jack Carter873c7242013-01-12 01:03:14 +0000274 };
275
276private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000277 enum KindTy {
278 k_CondCode,
279 k_CoprocNum,
280 k_Immediate,
281 k_Memory,
282 k_PostIndexRegister,
283 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000284 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000285 k_Token
286 } Kind;
287
288 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000289
Eric Christopher8996c5d2013-03-15 00:42:55 +0000290 struct Token {
291 const char *Data;
292 unsigned Length;
293 };
294
295 struct RegOp {
296 unsigned RegNum;
297 RegisterKind Kind;
298 };
299
300 struct ImmOp {
301 const MCExpr *Val;
302 };
303
304 struct MemOp {
305 unsigned Base;
306 const MCExpr *Off;
307 };
308
Jack Carterb4dbc172012-09-05 23:34:03 +0000309 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000310 struct Token Tok;
311 struct RegOp Reg;
312 struct ImmOp Imm;
313 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000314 };
315
316 SMLoc StartLoc, EndLoc;
317
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000318public:
319 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000320 assert(N == 1 && "Invalid number of operands!");
321 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000322 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000323
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000324 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
325 assert(N == 1 && "Invalid number of operands!");
326 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
327 }
328
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000329 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000330 // Add as immediate when possible. Null MCExpr = 0.
331 if (Expr == 0)
332 Inst.addOperand(MCOperand::CreateImm(0));
333 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
334 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
335 else
336 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000337 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000338
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000339 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000340 assert(N == 1 && "Invalid number of operands!");
341 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000342 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000343 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000344
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000345 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000346 assert(N == 2 && "Invalid number of operands!");
347
348 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
349
350 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000351 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000352 }
353
354 bool isReg() const { return Kind == k_Register; }
355 bool isImm() const { return Kind == k_Immediate; }
356 bool isToken() const { return Kind == k_Token; }
357 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000358 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000359 bool isInvNum() const { return Kind == k_Immediate; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000360
361 StringRef getToken() const {
362 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000363 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000364 }
365
366 unsigned getReg() const {
367 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000368 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000369 }
370
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000371 unsigned getPtrReg() const {
372 assert((Kind == k_PtrReg) && "Invalid access!");
373 return Reg.RegNum;
374 }
375
Jack Carter873c7242013-01-12 01:03:14 +0000376 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000377 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000378 Reg.Kind = RegKind;
379 }
380
Jack Carterb4dbc172012-09-05 23:34:03 +0000381 const MCExpr *getImm() const {
382 assert((Kind == k_Immediate) && "Invalid access!");
383 return Imm.Val;
384 }
385
Jack Carterdc1e35d2012-09-06 20:00:02 +0000386 unsigned getMemBase() const {
387 assert((Kind == k_Memory) && "Invalid access!");
388 return Mem.Base;
389 }
390
391 const MCExpr *getMemOff() const {
392 assert((Kind == k_Memory) && "Invalid access!");
393 return Mem.Off;
394 }
395
Jack Carterb4dbc172012-09-05 23:34:03 +0000396 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
397 MipsOperand *Op = new MipsOperand(k_Token);
398 Op->Tok.Data = Str.data();
399 Op->Tok.Length = Str.size();
400 Op->StartLoc = S;
401 Op->EndLoc = S;
402 return Op;
403 }
404
405 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
406 MipsOperand *Op = new MipsOperand(k_Register);
407 Op->Reg.RegNum = RegNum;
408 Op->StartLoc = S;
409 Op->EndLoc = E;
410 return Op;
411 }
412
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000413 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
414 MipsOperand *Op = new MipsOperand(k_PtrReg);
415 Op->Reg.RegNum = RegNum;
416 Op->StartLoc = S;
417 Op->EndLoc = E;
418 return Op;
419 }
420
Jack Carterb4dbc172012-09-05 23:34:03 +0000421 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
422 MipsOperand *Op = new MipsOperand(k_Immediate);
423 Op->Imm.Val = Val;
424 Op->StartLoc = S;
425 Op->EndLoc = E;
426 return Op;
427 }
428
Jack Carterdc1e35d2012-09-06 20:00:02 +0000429 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
430 SMLoc S, SMLoc E) {
431 MipsOperand *Op = new MipsOperand(k_Memory);
432 Op->Mem.Base = Base;
433 Op->Mem.Off = Off;
434 Op->StartLoc = S;
435 Op->EndLoc = E;
436 return Op;
437 }
438
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000439 bool isGPR32Asm() const {
440 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000441 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000442 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000443 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
444 }
445
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000446 bool isGPR64Asm() const {
447 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000448 }
Jack Carter873c7242013-01-12 01:03:14 +0000449
450 bool isHWRegsAsm() const {
451 assert((Kind == k_Register) && "Invalid access!");
452 return Reg.Kind == Kind_HWRegs;
453 }
Jack Carter873c7242013-01-12 01:03:14 +0000454
Jack Carter873c7242013-01-12 01:03:14 +0000455 bool isCCRAsm() const {
456 assert((Kind == k_Register) && "Invalid access!");
457 return Reg.Kind == Kind_CCRRegs;
458 }
459
Vladimir Medic233dd512013-06-24 10:05:34 +0000460 bool isAFGR64Asm() const {
461 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
462 }
463
464 bool isFGR64Asm() const {
465 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
466 }
467
468 bool isFGR32Asm() const {
469 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
470 }
471
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000472 bool isFGRH32Asm() const {
473 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
474 }
475
Vladimir Medic643b3982013-07-30 10:12:14 +0000476 bool isFCCRegsAsm() const {
477 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
478 }
479
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000480 bool isACC64DSPAsm() const {
481 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000482 }
483
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000484 bool isLO32DSPAsm() const {
485 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
486 }
487
488 bool isHI32DSPAsm() const {
489 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
490 }
491
Vladimir Medic05bcde62013-09-16 10:29:42 +0000492 bool isCOP2Asm() const {
493 return Kind == k_Register && Reg.Kind == Kind_COP2;
494 }
495
Jack Carter5dc8ac92013-09-25 23:50:44 +0000496 bool isMSA128BAsm() const {
497 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
498 }
499
500 bool isMSA128HAsm() const {
501 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
502 }
503
504 bool isMSA128WAsm() const {
505 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
506 }
507
508 bool isMSA128DAsm() const {
509 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
510 }
511
Jack Carterb4dbc172012-09-05 23:34:03 +0000512 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000513 SMLoc getStartLoc() const {
514 return StartLoc;
515 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000516 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000517 SMLoc getEndLoc() const {
518 return EndLoc;
519 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000520
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000521 virtual void print(raw_ostream &OS) const {
522 llvm_unreachable("unimplemented!");
523 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000524}; // class MipsOperand
525} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000526
Jack Carter9e65aa32013-03-22 00:05:30 +0000527namespace llvm {
528extern const MCInstrDesc MipsInsts[];
529}
530static const MCInstrDesc &getInstDesc(unsigned Opcode) {
531 return MipsInsts[Opcode];
532}
533
534bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000535 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000536 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
537 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000538 if (MCID.hasDelaySlot() && Options.isReorder()) {
539 // If this instruction has a delay slot and .set reorder is active,
540 // emit a NOP after it.
541 Instructions.push_back(Inst);
542 MCInst NopInst;
543 NopInst.setOpcode(Mips::SLL);
544 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
545 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
546 NopInst.addOperand(MCOperand::CreateImm(0));
547 Instructions.push_back(NopInst);
548 return false;
549 }
550
Jack Carter9e65aa32013-03-22 00:05:30 +0000551 if (MCID.mayLoad() || MCID.mayStore()) {
552 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000553 // reference or immediate we may have to expand instructions.
554 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000555 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000556 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
557 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000558 MCOperand &Op = Inst.getOperand(i);
559 if (Op.isImm()) {
560 int MemOffset = Op.getImm();
561 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000562 // Offset can't exceed 16bit value.
563 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000564 return false;
565 }
566 } else if (Op.isExpr()) {
567 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000568 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000569 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000570 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000571 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000572 // Expand symbol.
573 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000574 return false;
575 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000576 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000577 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000578 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000579 }
580 }
581 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000582 } // for
583 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000584
585 if (needsExpansion(Inst))
586 expandInstruction(Inst, IDLoc, Instructions);
587 else
588 Instructions.push_back(Inst);
589
590 return false;
591}
592
Jack Carter30a59822012-10-04 04:03:53 +0000593bool MipsAsmParser::needsExpansion(MCInst &Inst) {
594
Jack Carterd0bd6422013-04-18 00:41:53 +0000595 switch (Inst.getOpcode()) {
596 case Mips::LoadImm32Reg:
597 case Mips::LoadAddr32Imm:
598 case Mips::LoadAddr32Reg:
599 return true;
600 default:
601 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000602 }
603}
Jack Carter92995f12012-10-06 00:53:28 +0000604
Jack Carter30a59822012-10-04 04:03:53 +0000605void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000606 SmallVectorImpl<MCInst> &Instructions) {
607 switch (Inst.getOpcode()) {
608 case Mips::LoadImm32Reg:
609 return expandLoadImm(Inst, IDLoc, Instructions);
610 case Mips::LoadAddr32Imm:
611 return expandLoadAddressImm(Inst, IDLoc, Instructions);
612 case Mips::LoadAddr32Reg:
613 return expandLoadAddressReg(Inst, IDLoc, Instructions);
614 }
Jack Carter30a59822012-10-04 04:03:53 +0000615}
Jack Carter92995f12012-10-06 00:53:28 +0000616
Jack Carter30a59822012-10-04 04:03:53 +0000617void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000618 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000619 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000620 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000621 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000622 const MCOperand &RegOp = Inst.getOperand(0);
623 assert(RegOp.isReg() && "expected register operand kind");
624
625 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000626 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000627 if (0 <= ImmValue && ImmValue <= 65535) {
628 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000629 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000630 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000631 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000632 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000633 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000634 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000635 } else if (ImmValue < 0 && ImmValue >= -32768) {
636 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000637 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000638 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000639 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000640 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000641 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000642 Instructions.push_back(tmpInst);
643 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000644 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000645 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000646 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000647 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000648 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
649 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000650 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000651 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000652 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000653 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
654 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
655 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
656 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000657 Instructions.push_back(tmpInst);
658 }
659}
Jack Carter92995f12012-10-06 00:53:28 +0000660
Jack Carter543fdf82012-10-09 23:29:45 +0000661void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000662 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000663 MCInst tmpInst;
664 const MCOperand &ImmOp = Inst.getOperand(2);
665 assert(ImmOp.isImm() && "expected immediate operand kind");
666 const MCOperand &SrcRegOp = Inst.getOperand(1);
667 assert(SrcRegOp.isReg() && "expected register operand kind");
668 const MCOperand &DstRegOp = Inst.getOperand(0);
669 assert(DstRegOp.isReg() && "expected register operand kind");
670 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000671 if (-32768 <= ImmValue && ImmValue <= 65535) {
672 // For -32768 <= j <= 65535.
673 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000674 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000675 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
676 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
677 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
678 Instructions.push_back(tmpInst);
679 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000680 // For any other value of j that is representable as a 32-bit integer.
681 // la d,j(s) => lui d,hi16(j)
682 // ori d,d,lo16(j)
683 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000684 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000685 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
686 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
687 Instructions.push_back(tmpInst);
688 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000689 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000690 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
691 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
692 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
693 Instructions.push_back(tmpInst);
694 tmpInst.clear();
695 tmpInst.setOpcode(Mips::ADDu);
696 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
697 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
698 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
699 Instructions.push_back(tmpInst);
700 }
701}
702
703void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000704 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000705 MCInst tmpInst;
706 const MCOperand &ImmOp = Inst.getOperand(1);
707 assert(ImmOp.isImm() && "expected immediate operand kind");
708 const MCOperand &RegOp = Inst.getOperand(0);
709 assert(RegOp.isReg() && "expected register operand kind");
710 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000711 if (-32768 <= ImmValue && ImmValue <= 65535) {
712 // For -32768 <= j <= 65535.
713 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000714 tmpInst.setOpcode(Mips::ADDiu);
715 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000716 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000717 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
718 Instructions.push_back(tmpInst);
719 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000720 // For any other value of j that is representable as a 32-bit integer.
721 // la d,j => lui d,hi16(j)
722 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000723 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000724 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
725 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
726 Instructions.push_back(tmpInst);
727 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000728 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000729 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
730 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
731 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
732 Instructions.push_back(tmpInst);
733 }
734}
735
Jack Carter9e65aa32013-03-22 00:05:30 +0000736void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000737 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000738 const MCSymbolRefExpr *SR;
739 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000740 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000741 const MCExpr *ExprOffset;
742 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000743 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
744 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000745 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000746 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
747 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000748 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000749 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
750 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000751 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000752 if (isImmOpnd) {
753 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
754 ImmOffset = Inst.getOperand(2).getImm();
755 LoOffset = ImmOffset & 0x0000ffff;
756 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000757 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000758 if (LoOffset & 0x8000)
759 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000760 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000761 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000762 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000763 TempInst.setLoc(IDLoc);
764 // 1st instruction in expansion is LUi. For load instruction we can use
765 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000766 // but for stores we must use $at.
767 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000768 TempInst.setOpcode(Mips::LUi);
769 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
770 if (isImmOpnd)
771 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
772 else {
773 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
774 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000775 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
776 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
777 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000778 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000779 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000780 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000781 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000782 }
783 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000784 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000785 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000786 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000787 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000788 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000789 TempInst.setOpcode(Mips::ADDu);
790 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
791 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
792 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
793 Instructions.push_back(TempInst);
794 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000795 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000796 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000797 TempInst.setOpcode(Inst.getOpcode());
798 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
799 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
800 if (isImmOpnd)
801 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
802 else {
803 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000804 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
805 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
806 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000807 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000808 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000809 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000810 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000811 }
812 }
813 Instructions.push_back(TempInst);
814 TempInst.clear();
815}
816
Rafael Espindola870c4e92012-01-11 03:56:41 +0000817bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000818MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000819 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000820 MCStreamer &Out, unsigned &ErrorInfo,
821 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000822 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000823 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000824 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000825 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000826
827 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000828 default:
829 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000830 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000831 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000832 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000833 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000834 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000835 return false;
836 }
837 case Match_MissingFeature:
838 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
839 return true;
840 case Match_InvalidOperand: {
841 SMLoc ErrorLoc = IDLoc;
842 if (ErrorInfo != ~0U) {
843 if (ErrorInfo >= Operands.size())
844 return Error(IDLoc, "too few operands for instruction");
845
Jack Carterd0bd6422013-04-18 00:41:53 +0000846 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
847 if (ErrorLoc == SMLoc())
848 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000849 }
850
851 return Error(ErrorLoc, "invalid operand for instruction");
852 }
853 case Match_MnemonicFail:
854 return Error(IDLoc, "invalid instruction");
855 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000856 return true;
857}
858
Jack Carter1ac53222013-02-20 23:11:17 +0000859int MipsAsmParser::matchCPURegisterName(StringRef Name) {
860 int CC;
861
862 if (Name == "at")
863 return getATReg();
864
865 CC = StringSwitch<unsigned>(Name)
866 .Case("zero", 0)
867 .Case("a0", 4)
868 .Case("a1", 5)
869 .Case("a2", 6)
870 .Case("a3", 7)
871 .Case("v0", 2)
872 .Case("v1", 3)
873 .Case("s0", 16)
874 .Case("s1", 17)
875 .Case("s2", 18)
876 .Case("s3", 19)
877 .Case("s4", 20)
878 .Case("s5", 21)
879 .Case("s6", 22)
880 .Case("s7", 23)
881 .Case("k0", 26)
882 .Case("k1", 27)
883 .Case("sp", 29)
884 .Case("fp", 30)
885 .Case("gp", 28)
886 .Case("ra", 31)
887 .Case("t0", 8)
888 .Case("t1", 9)
889 .Case("t2", 10)
890 .Case("t3", 11)
891 .Case("t4", 12)
892 .Case("t5", 13)
893 .Case("t6", 14)
894 .Case("t7", 15)
895 .Case("t8", 24)
896 .Case("t9", 25)
897 .Default(-1);
898
Jack Carterd0bd6422013-04-18 00:41:53 +0000899 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000900 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
901 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000902 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000903 CC += 4;
904
905 if (CC == -1 && isMips64())
906 CC = StringSwitch<unsigned>(Name)
907 .Case("a4", 8)
908 .Case("a5", 9)
909 .Case("a6", 10)
910 .Case("a7", 11)
911 .Case("kt0", 26)
912 .Case("kt1", 27)
913 .Case("s8", 30)
914 .Default(-1);
915
916 return CC;
917}
Jack Carterd0bd6422013-04-18 00:41:53 +0000918
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000919int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000920
Jack Cartera63b16a2012-09-07 00:23:42 +0000921 if (Name[0] == 'f') {
922 StringRef NumString = Name.substr(1);
923 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000924 if (NumString.getAsInteger(10, IntVal))
925 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000926 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000927 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000928 return IntVal;
929 }
930 return -1;
931}
Jack Cartera63b16a2012-09-07 00:23:42 +0000932
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000933int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
934
935 if (Name.startswith("fcc")) {
936 StringRef NumString = Name.substr(3);
937 unsigned IntVal;
938 if (NumString.getAsInteger(10, IntVal))
939 return -1; // This is not an integer.
940 if (IntVal > 7) // There are only 8 fcc registers.
941 return -1;
942 return IntVal;
943 }
944 return -1;
945}
946
947int MipsAsmParser::matchACRegisterName(StringRef Name) {
948
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000949 if (Name.startswith("ac")) {
950 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000951 unsigned IntVal;
952 if (NumString.getAsInteger(10, IntVal))
953 return -1; // This is not an integer.
954 if (IntVal > 3) // There are only 3 acc registers.
955 return -1;
956 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000957 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000958 return -1;
959}
Jack Carterd0bd6422013-04-18 00:41:53 +0000960
Jack Carter5dc8ac92013-09-25 23:50:44 +0000961int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
962 unsigned IntVal;
963
964 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
965 return -1;
966
967 if (IntVal > 31)
968 return -1;
969
970 return IntVal;
971}
972
Vladimir Medic8cd17102013-06-20 11:21:49 +0000973int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
974
Vladimir Medic8cd17102013-06-20 11:21:49 +0000975 int CC;
976 CC = matchCPURegisterName(Name);
977 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000978 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
979 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000980 CC = matchFPURegisterName(Name);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000981 //TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +0000982 if (CC != -1)
983 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
984 : Mips::FGR32RegClassID);
985 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000986}
987
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000988int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000989
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000990 switch (RegKind) {
991 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
992 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
993 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
994 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000995 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000996 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
997 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
998 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
999 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
1000 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
Jack Carter5dc8ac92013-09-25 23:50:44 +00001001 case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
1002 case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
1003 case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
1004 case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001005 default :return -1;
1006 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001007
Jack Cartera63b16a2012-09-07 00:23:42 +00001008}
Jack Carterb4dbc172012-09-05 23:34:03 +00001009
Jack Carter0b744b32012-10-04 02:29:46 +00001010bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1011 if (Reg > 31)
1012 return false;
1013
1014 aTReg = Reg;
1015 return true;
1016}
1017
Jack Carter1ac53222013-02-20 23:11:17 +00001018int MipsAsmParser::getATReg() {
1019 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +00001020}
1021
Jack Carterd0bd6422013-04-18 00:41:53 +00001022unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001023 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001024}
1025
Jack Carter873c7242013-01-12 01:03:14 +00001026int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001027 if (RegNum >
1028 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001029 return -1;
1030
Jack Carter873c7242013-01-12 01:03:14 +00001031 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001032}
1033
Jack Carter873c7242013-01-12 01:03:14 +00001034int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001035 const AsmToken &Tok = Parser.getTok();
1036 int RegNum = -1;
1037
1038 if (Tok.is(AsmToken::Identifier)) {
1039 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001040 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001041 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001042 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001043 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001044 return RegNum;
1045}
1046
Jack Carterd0bd6422013-04-18 00:41:53 +00001047bool MipsAsmParser::tryParseRegisterOperand(
1048 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001049
1050 SMLoc S = Parser.getTok().getLoc();
1051 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001052
Jack Carter873c7242013-01-12 01:03:14 +00001053 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001054 if (RegNo == -1)
1055 return true;
1056
Jack Carter873c7242013-01-12 01:03:14 +00001057 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +00001058 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001059 Parser.Lex(); // Eat register token.
1060 return false;
1061}
1062
1063bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1064 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001065 // Check if the current operand has a custom associated parser, if so, try to
1066 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001067 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1068 if (ResTy == MatchOperand_Success)
1069 return false;
1070 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1071 // there was a match, but an error occurred, in which case, just return that
1072 // the operand parsing failed.
1073 if (ResTy == MatchOperand_ParseFail)
1074 return true;
1075
1076 switch (getLexer().getKind()) {
1077 default:
1078 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1079 return true;
1080 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001081 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001082 SMLoc S = Parser.getTok().getLoc();
1083 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001084 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001085 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001086 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001087 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001088 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001089 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001090 if (getLexer().isNot(AsmToken::Dollar))
1091 return true;
1092
Jack Carterd0bd6422013-04-18 00:41:53 +00001093 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001094 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001095 return true;
1096
1097 if (!getLexer().is(AsmToken::RParen))
1098 return true;
1099
1100 S = Parser.getTok().getLoc();
1101 Operands.push_back(MipsOperand::CreateToken(")", S));
1102 Parser.Lex();
1103 }
1104 return false;
1105 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001106 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001107 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001108 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001109 return true;
1110
Jack Carter873c7242013-01-12 01:03:14 +00001111 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001112
Benjamin Kramerfa530572012-09-07 09:47:42 +00001113 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001114
Jack Carterd0bd6422013-04-18 00:41:53 +00001115 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001116 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001117 getContext());
1118
1119 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1120 return false;
1121 }
1122 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001123 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001124 // we need to assigne the propper RegisterKind.
1125 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1126 return false;
1127 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001128 case AsmToken::LParen:
1129 case AsmToken::Minus:
1130 case AsmToken::Plus:
1131 case AsmToken::Integer:
1132 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001133 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001134 const MCExpr *IdVal;
1135 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001136 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001137 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001138 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001139 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1140 return false;
1141 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001142 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001143 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001144 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001145 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001146 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001147 return true;
1148
Jack Carter873c7242013-01-12 01:03:14 +00001149 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1150
Jack Carterdc1e35d2012-09-06 20:00:02 +00001151 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1152 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001153 } // case AsmToken::Percent
1154 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001155 return true;
1156}
1157
Jack Carterb5cf5902013-04-17 00:18:04 +00001158const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1159 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001160 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001161 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001162 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001163 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001164 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001165 short Val = MCE->getValue();
1166 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001167 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001168 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001169 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001170 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001171 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001172 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001173 if (LoSign)
1174 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001175 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001176 } else {
1177 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001178 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001179 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001180 }
1181
Jack Carterb5cf5902013-04-17 00:18:04 +00001182 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001183 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001184 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001185 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001186 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001187 return Res;
1188 }
1189
1190 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001191 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1192 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001193 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1194 return Res;
1195 }
1196
1197 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001198 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1199 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1200 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001201 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001202 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001203 return Expr;
1204}
1205
1206bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1207
1208 switch (Expr->getKind()) {
1209 case MCExpr::Constant:
1210 return true;
1211 case MCExpr::SymbolRef:
1212 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1213 case MCExpr::Binary:
1214 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1215 if (!isEvaluated(BE->getLHS()))
1216 return false;
1217 return isEvaluated(BE->getRHS());
1218 }
1219 case MCExpr::Unary:
1220 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1221 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001222 return false;
1223 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001224 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001225}
Jack Carterd0bd6422013-04-18 00:41:53 +00001226
Jack Carterb5cf5902013-04-17 00:18:04 +00001227bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001228 Parser.Lex(); // Eat the % token.
1229 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001230 if (Tok.isNot(AsmToken::Identifier))
1231 return true;
1232
1233 std::string Str = Tok.getIdentifier().str();
1234
Jack Carterd0bd6422013-04-18 00:41:53 +00001235 Parser.Lex(); // Eat the identifier.
1236 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001237 const MCExpr *IdVal;
1238 SMLoc EndLoc;
1239
1240 if (getLexer().getKind() == AsmToken::LParen) {
1241 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001242 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001243 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001244 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001245 const AsmToken &nextTok = Parser.getTok();
1246 if (nextTok.isNot(AsmToken::Identifier))
1247 return true;
1248 Str += "(%";
1249 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001250 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001251 if (getLexer().getKind() != AsmToken::LParen)
1252 return true;
1253 } else
1254 break;
1255 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001256 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001257 return true;
1258
1259 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001260 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001261
1262 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001263 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001264
Jack Carterd0bd6422013-04-18 00:41:53 +00001265 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001266 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001267}
1268
Jack Carterb4dbc172012-09-05 23:34:03 +00001269bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1270 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001271 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001272 RegNo = tryParseRegister(isMips64());
1273 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001274 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001275}
1276
Jack Carterb5cf5902013-04-17 00:18:04 +00001277bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001278 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001279 bool Result = true;
1280
1281 while (getLexer().getKind() == AsmToken::LParen)
1282 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001283
Jack Carterd0bd6422013-04-18 00:41:53 +00001284 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001285 default:
1286 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001287 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001288 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001289 case AsmToken::Integer:
1290 case AsmToken::Minus:
1291 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001292 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001293 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001294 else
1295 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001296 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001297 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001298 break;
Jack Carter873c7242013-01-12 01:03:14 +00001299 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001300 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001301 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001302 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001303}
1304
Jack Carterb4dbc172012-09-05 23:34:03 +00001305MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001306 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001307
1308 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001309 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001310 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001311 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001312 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001313 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001314
Jack Carterb5cf5902013-04-17 00:18:04 +00001315 if (getLexer().getKind() == AsmToken::LParen) {
1316 Parser.Lex();
1317 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001318 }
1319
Jack Carterb5cf5902013-04-17 00:18:04 +00001320 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001321 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001322 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001323
Jack Carterd0bd6422013-04-18 00:41:53 +00001324 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001325 if (Tok.isNot(AsmToken::LParen)) {
1326 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1327 if (Mnemonic->getToken() == "la") {
1328 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001329 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001330 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1331 return MatchOperand_Success;
1332 }
1333 if (Tok.is(AsmToken::EndOfStatement)) {
1334 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001335 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001336
Jack Carterd0bd6422013-04-18 00:41:53 +00001337 // Zero register assumed, add a memory operand with ZERO as its base.
1338 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1339 : Mips::ZERO,
1340 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001341 return MatchOperand_Success;
1342 }
1343 Error(Parser.getTok().getLoc(), "'(' expected");
1344 return MatchOperand_ParseFail;
1345 }
1346
Jack Carterd0bd6422013-04-18 00:41:53 +00001347 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001348 }
1349
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001350 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1351 (int) MipsOperand::Kind_GPR32);
1352 if (Res != MatchOperand_Success)
1353 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001354
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001355 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001356 Error(Parser.getTok().getLoc(), "')' expected");
1357 return MatchOperand_ParseFail;
1358 }
1359
Jack Carter873c7242013-01-12 01:03:14 +00001360 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1361
Jack Carterd0bd6422013-04-18 00:41:53 +00001362 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001363
1364 if (IdVal == 0)
1365 IdVal = MCConstantExpr::Create(0, getContext());
1366
Jack Carterd0bd6422013-04-18 00:41:53 +00001367 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001368 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1369 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001370 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001371 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001372 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001373 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1374 int64_t Imm;
1375 if (IdVal->EvaluateAsAbsolute(Imm))
1376 IdVal = MCConstantExpr::Create(Imm, getContext());
1377 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1378 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1379 getContext());
1380 }
1381
Jack Carterdc1e35d2012-09-06 20:00:02 +00001382 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1383 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001384 return MatchOperand_Success;
1385}
1386
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001387bool
1388MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1389 int RegKind) {
1390 // If the first token is not '$' we have an error.
1391 if (Parser.getTok().isNot(AsmToken::Dollar))
1392 return false;
1393
1394 SMLoc S = Parser.getTok().getLoc();
1395 Parser.Lex();
1396 AsmToken::TokenKind TkKind = getLexer().getKind();
1397 int Reg;
1398
1399 if (TkKind == AsmToken::Integer) {
1400 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1401 regKindToRegClass(RegKind));
1402 if (Reg == -1)
1403 return false;
1404 } else if (TkKind == AsmToken::Identifier) {
1405 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1406 return false;
1407 Reg = getReg(regKindToRegClass(RegKind), Reg);
1408 } else {
1409 return false;
1410 }
1411
1412 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1413 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1414 Operands.push_back(Op);
1415 Parser.Lex();
1416 return true;
1417}
1418
1419MipsAsmParser::OperandMatchResultTy
1420MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1421 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1422 MipsOperand::Kind_GPR32;
1423
1424 // Parse index register.
1425 if (!parsePtrReg(Operands, RegKind))
1426 return MatchOperand_NoMatch;
1427
1428 // Parse '('.
1429 if (Parser.getTok().isNot(AsmToken::LParen))
1430 return MatchOperand_NoMatch;
1431
1432 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1433 Parser.Lex();
1434
1435 // Parse base register.
1436 if (!parsePtrReg(Operands, RegKind))
1437 return MatchOperand_NoMatch;
1438
1439 // Parse ')'.
1440 if (Parser.getTok().isNot(AsmToken::RParen))
1441 return MatchOperand_NoMatch;
1442
1443 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1444 Parser.Lex();
1445
1446 return MatchOperand_Success;
1447}
1448
Jack Carter873c7242013-01-12 01:03:14 +00001449MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001450MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1451 int RegKind) {
1452 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001453 if (getLexer().getKind() == AsmToken::Identifier
1454 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001455 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001456 return MatchOperand_Success;
1457 return MatchOperand_NoMatch;
1458 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001459 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001460 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001461 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001462 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001463 if (!hasConsumedDollar) {
1464 Parser.Lex(); // Eat the '$'
1465 hasConsumedDollar = true;
1466 }
1467 if (getLexer().getKind() == AsmToken::Identifier) {
1468 int RegNum = -1;
1469 std::string RegName = Parser.getTok().getString().lower();
1470 // Match register by name
1471 switch (RegKind) {
1472 case MipsOperand::Kind_GPR32:
1473 case MipsOperand::Kind_GPR64:
1474 RegNum = matchCPURegisterName(RegName);
1475 break;
1476 case MipsOperand::Kind_AFGR64Regs:
1477 case MipsOperand::Kind_FGR64Regs:
1478 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001479 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001480 RegNum = matchFPURegisterName(RegName);
1481 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1482 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001483 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1484 && !isFP64())
1485 if (RegNum != -1 && RegNum %2 != 0)
1486 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001487 break;
1488 case MipsOperand::Kind_FCCRegs:
1489 RegNum = matchFCCRegisterName(RegName);
1490 break;
1491 case MipsOperand::Kind_ACC64DSP:
1492 RegNum = matchACRegisterName(RegName);
1493 break;
1494 default: break; // No match, value is set to -1.
1495 }
1496 // No match found, return _NoMatch to give a chance to other round.
1497 if (RegNum < 0)
1498 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001499
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001500 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1501 if (RegVal == -1)
1502 return MatchOperand_NoMatch;
1503
1504 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1505 Parser.getTok().getLoc());
1506 Op->setRegKind(Kind);
1507 Operands.push_back(Op);
1508 hasConsumedDollar = false;
1509 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001510 return MatchOperand_Success;
1511 } else if (getLexer().getKind() == AsmToken::Integer) {
1512 unsigned RegNum = Parser.getTok().getIntVal();
1513 if (Kind == MipsOperand::Kind_HWRegs) {
1514 if (RegNum != 29)
1515 return MatchOperand_NoMatch;
1516 // Only hwreg 29 is supported, found at index 0.
1517 RegNum = 0;
1518 }
1519 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1520 if (Reg == -1)
1521 return MatchOperand_NoMatch;
1522 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1523 Op->setRegKind(Kind);
1524 Operands.push_back(Op);
1525 hasConsumedDollar = false;
1526 Parser.Lex(); // Eat the register number.
1527 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001528 && (getLexer().is(AsmToken::LParen))) {
1529 // Check if it is indexed addressing operand.
1530 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1531 Parser.Lex(); // Eat the parenthesis.
1532 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1533 return MatchOperand_NoMatch;
1534 if (getLexer().isNot(AsmToken::RParen))
1535 return MatchOperand_NoMatch;
1536 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1537 Parser.Lex();
1538 }
Jack Carter873c7242013-01-12 01:03:14 +00001539 return MatchOperand_Success;
1540 }
1541 return MatchOperand_NoMatch;
1542}
Vladimir Medic64828a12013-07-16 10:07:14 +00001543
Vladimir Medic8cd17102013-06-20 11:21:49 +00001544MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +00001545MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1546 int RegKind) {
1547 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1548 SMLoc S = Parser.getTok().getLoc();
1549 std::string RegName;
1550
1551 if (Parser.getTok().isNot(AsmToken::Dollar))
1552 return MatchOperand_NoMatch;
1553
1554 switch (RegKind) {
1555 default:
1556 return MatchOperand_ParseFail;
1557 case MipsOperand::Kind_MSA128BRegs:
1558 case MipsOperand::Kind_MSA128HRegs:
1559 case MipsOperand::Kind_MSA128WRegs:
1560 case MipsOperand::Kind_MSA128DRegs:
1561 break;
1562 }
1563
1564 Parser.Lex(); // Eat the '$'.
1565 if (getLexer().getKind() == AsmToken::Identifier)
1566 RegName = Parser.getTok().getString().lower();
1567 else
1568 return MatchOperand_ParseFail;
1569
1570 int RegNum = matchMSA128RegisterName(RegName);
1571
1572 if (RegNum < 0 || RegNum > 31)
1573 return MatchOperand_ParseFail;
1574
1575 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1576 if (RegVal == -1)
1577 return MatchOperand_ParseFail;
1578
1579 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1580 Parser.getTok().getLoc());
1581 Op->setRegKind(Kind);
1582 Operands.push_back(Op);
1583
1584 Parser.Lex(); // Eat the register identifier.
1585
1586 return MatchOperand_Success;
1587}
1588
1589MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001590MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001591
1592 if (!isMips64())
1593 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001594 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001595}
1596
1597MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001598MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1599 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001600}
Jack Carter873c7242013-01-12 01:03:14 +00001601
Vladimir Medic233dd512013-06-24 10:05:34 +00001602MipsAsmParser::OperandMatchResultTy
1603MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1604
1605 if (isFP64())
1606 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001607 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1608}
1609
1610MipsAsmParser::OperandMatchResultTy
1611MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1612 if (!isFP64())
1613 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001614 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1615}
1616
1617MipsAsmParser::OperandMatchResultTy
1618MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001619 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1620}
1621
Vladimir Medic643b3982013-07-30 10:12:14 +00001622MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001623MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1624 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1625}
1626
1627MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001628MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001629 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001630}
1631
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001632MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001633MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001634 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001635}
1636
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001637MipsAsmParser::OperandMatchResultTy
1638MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1639 // If the first token is not '$' we have an error.
1640 if (Parser.getTok().isNot(AsmToken::Dollar))
1641 return MatchOperand_NoMatch;
1642
1643 SMLoc S = Parser.getTok().getLoc();
1644 Parser.Lex(); // Eat the '$'
1645
1646 const AsmToken &Tok = Parser.getTok(); // Get next token.
1647
1648 if (Tok.isNot(AsmToken::Identifier))
1649 return MatchOperand_NoMatch;
1650
1651 if (!Tok.getIdentifier().startswith("ac"))
1652 return MatchOperand_NoMatch;
1653
1654 StringRef NumString = Tok.getIdentifier().substr(2);
1655
1656 unsigned IntVal;
1657 if (NumString.getAsInteger(10, IntVal))
1658 return MatchOperand_NoMatch;
1659
1660 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1661
1662 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1663 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1664 Operands.push_back(Op);
1665
1666 Parser.Lex(); // Eat the register number.
1667 return MatchOperand_Success;
1668}
1669
1670MipsAsmParser::OperandMatchResultTy
1671MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1672 // If the first token is not '$' we have an error.
1673 if (Parser.getTok().isNot(AsmToken::Dollar))
1674 return MatchOperand_NoMatch;
1675
1676 SMLoc S = Parser.getTok().getLoc();
1677 Parser.Lex(); // Eat the '$'
1678
1679 const AsmToken &Tok = Parser.getTok(); // Get next token.
1680
1681 if (Tok.isNot(AsmToken::Identifier))
1682 return MatchOperand_NoMatch;
1683
1684 if (!Tok.getIdentifier().startswith("ac"))
1685 return MatchOperand_NoMatch;
1686
1687 StringRef NumString = Tok.getIdentifier().substr(2);
1688
1689 unsigned IntVal;
1690 if (NumString.getAsInteger(10, IntVal))
1691 return MatchOperand_NoMatch;
1692
1693 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1694
1695 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1696 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1697 Operands.push_back(Op);
1698
1699 Parser.Lex(); // Eat the register number.
1700 return MatchOperand_Success;
1701}
1702
Vladimir Medic05bcde62013-09-16 10:29:42 +00001703MipsAsmParser::OperandMatchResultTy
1704MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1705 // If the first token is not '$' we have an error.
1706 if (Parser.getTok().isNot(AsmToken::Dollar))
1707 return MatchOperand_NoMatch;
1708
1709 SMLoc S = Parser.getTok().getLoc();
1710 Parser.Lex(); // Eat the '$'
1711
1712 const AsmToken &Tok = Parser.getTok(); // Get next token.
1713
1714 if (Tok.isNot(AsmToken::Integer))
1715 return MatchOperand_NoMatch;
1716
1717 unsigned IntVal = Tok.getIntVal();
1718
1719 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1720
1721 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1722 Op->setRegKind(MipsOperand::Kind_COP2);
1723 Operands.push_back(Op);
1724
1725 Parser.Lex(); // Eat the register number.
1726 return MatchOperand_Success;
1727}
1728
Jack Carter5dc8ac92013-09-25 23:50:44 +00001729MipsAsmParser::OperandMatchResultTy
1730MipsAsmParser::parseMSA128BRegs(
1731 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1732 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
1733}
1734
1735MipsAsmParser::OperandMatchResultTy
1736MipsAsmParser::parseMSA128HRegs(
1737 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1738 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
1739}
1740
1741MipsAsmParser::OperandMatchResultTy
1742MipsAsmParser::parseMSA128WRegs(
1743 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1744 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
1745}
1746
1747MipsAsmParser::OperandMatchResultTy
1748MipsAsmParser::parseMSA128DRegs(
1749 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1750 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
1751}
1752
Jack Carterd0bd6422013-04-18 00:41:53 +00001753bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001754 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001755
1756 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1757 if (Sym) {
1758 SMLoc S = Parser.getTok().getLoc();
1759 const MCExpr *Expr;
1760 if (Sym->isVariable())
1761 Expr = Sym->getVariableValue();
1762 else
1763 return false;
1764 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001765 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001766 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1767 const StringRef DefSymbol = Ref->getSymbol().getName();
1768 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001769 int RegNum = -1;
1770 APInt IntVal(32, -1);
1771 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1772 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001773 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001774 ? Mips::GPR64RegClassID
1775 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001776 else {
1777 // Lookup for the register with the corresponding name.
1778 switch (Kind) {
1779 case MipsOperand::Kind_AFGR64Regs:
1780 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001781 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001782 break;
1783 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001784 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001785 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001786 case MipsOperand::Kind_GPR64:
1787 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001788 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001789 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001790 break;
1791 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001792 if (RegNum > -1)
1793 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001794 }
Jack Carterd76b2372013-03-21 21:44:16 +00001795 if (RegNum > -1) {
1796 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001797 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1798 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001799 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001800 Operands.push_back(op);
1801 return true;
1802 }
1803 }
1804 } else if (Expr->getKind() == MCExpr::Constant) {
1805 Parser.Lex();
1806 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001807 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001808 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001809 Operands.push_back(op);
1810 return true;
1811 }
1812 }
1813 return false;
1814}
Jack Carterd0bd6422013-04-18 00:41:53 +00001815
Jack Carter873c7242013-01-12 01:03:14 +00001816MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001817MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001818 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001819}
1820
1821MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001822MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001823 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001824}
1825
Vladimir Medic2b953d02013-10-01 09:48:56 +00001826MipsAsmParser::OperandMatchResultTy
1827MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1828 const MCExpr *IdVal;
1829 // If the first token is '$' we may have register operand.
1830 if (Parser.getTok().is(AsmToken::Dollar))
1831 return MatchOperand_NoMatch;
1832 SMLoc S = Parser.getTok().getLoc();
1833 if (getParser().parseExpression(IdVal))
1834 return MatchOperand_ParseFail;
1835 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
1836 assert( MCE && "Unexpected MCExpr type.");
1837 int64_t Val = MCE->getValue();
1838 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1839 Operands.push_back(MipsOperand::CreateImm(
1840 MCConstantExpr::Create(0 - Val, getContext()), S, E));
1841 return MatchOperand_Success;
1842}
1843
Jack Carterdc1e35d2012-09-06 20:00:02 +00001844MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1845
1846 MCSymbolRefExpr::VariantKind VK
1847 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1848 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1849 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1850 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1851 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1852 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1853 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1854 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1855 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1856 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1857 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1858 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1859 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1860 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1861 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1862 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1863 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1864 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1865 .Default(MCSymbolRefExpr::VK_None);
1866
1867 return VK;
1868}
Jack Cartera63b16a2012-09-07 00:23:42 +00001869
Rafael Espindola870c4e92012-01-11 03:56:41 +00001870bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001871ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001872 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001873 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001874 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001875 Parser.eatToEndOfStatement();
1876 return Error(NameLoc, "Unknown instruction");
1877 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001878 // First operand in MCInst is instruction mnemonic.
1879 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001880
1881 // Read the remaining operands.
1882 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1883 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001884 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001885 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001886 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001887 return Error(Loc, "unexpected token in argument list");
1888 }
1889
Jack Carterd0bd6422013-04-18 00:41:53 +00001890 while (getLexer().is(AsmToken::Comma)) {
1891 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001892 // Parse and remember the operand.
1893 if (ParseOperand(Operands, Name)) {
1894 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001895 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001896 return Error(Loc, "unexpected token in argument list");
1897 }
1898 }
1899 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001900 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1901 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001902 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001903 return Error(Loc, "unexpected token in argument list");
1904 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001905 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001906 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001907}
1908
Jack Carter0b744b32012-10-04 02:29:46 +00001909bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001910 SMLoc Loc = getLexer().getLoc();
1911 Parser.eatToEndOfStatement();
1912 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001913}
1914
1915bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001916 // Line should look like: ".set noat".
1917 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001918 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001919 // eat noat
1920 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001921 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001922 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1923 reportParseError("unexpected token in statement");
1924 return false;
1925 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001926 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001927 return false;
1928}
Jack Carterd0bd6422013-04-18 00:41:53 +00001929
Jack Carter0b744b32012-10-04 02:29:46 +00001930bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001931 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001932 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001933 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001934 getParser().Lex();
1935 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001936 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001937 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001938 return false;
1939 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001940 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001941 if (getLexer().isNot(AsmToken::Dollar)) {
1942 reportParseError("unexpected token in statement");
1943 return false;
1944 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001945 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001946 const AsmToken &Reg = Parser.getTok();
1947 if (Reg.is(AsmToken::Identifier)) {
1948 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1949 } else if (Reg.is(AsmToken::Integer)) {
1950 AtRegNo = Reg.getIntVal();
1951 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001952 reportParseError("unexpected token in statement");
1953 return false;
1954 }
Jack Carter1ac53222013-02-20 23:11:17 +00001955
Jack Carterd0bd6422013-04-18 00:41:53 +00001956 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001957 reportParseError("unexpected token in statement");
1958 return false;
1959 }
1960
1961 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001962 reportParseError("unexpected token in statement");
1963 return false;
1964 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001965 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001966
1967 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1968 reportParseError("unexpected token in statement");
1969 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001970 }
1971 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001972 return false;
1973 } else {
1974 reportParseError("unexpected token in statement");
1975 return false;
1976 }
1977}
1978
1979bool MipsAsmParser::parseSetReorderDirective() {
1980 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001981 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001982 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1983 reportParseError("unexpected token in statement");
1984 return false;
1985 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001986 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001987 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001988 return false;
1989}
1990
1991bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001992 Parser.Lex();
1993 // If this is not the end of the statement, report an error.
1994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1995 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001996 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001997 }
1998 Options.setNoreorder();
1999 Parser.Lex(); // Consume the EndOfStatement.
2000 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002001}
2002
2003bool MipsAsmParser::parseSetMacroDirective() {
2004 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002005 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002006 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2007 reportParseError("unexpected token in statement");
2008 return false;
2009 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002010 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002011 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002012 return false;
2013}
2014
2015bool MipsAsmParser::parseSetNoMacroDirective() {
2016 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002017 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002018 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2019 reportParseError("`noreorder' must be set before `nomacro'");
2020 return false;
2021 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002022 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002023 reportParseError("`noreorder' must be set before `nomacro'");
2024 return false;
2025 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002026 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002027 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002028 return false;
2029}
Jack Carterd76b2372013-03-21 21:44:16 +00002030
2031bool MipsAsmParser::parseSetAssignment() {
2032 StringRef Name;
2033 const MCExpr *Value;
2034
2035 if (Parser.parseIdentifier(Name))
2036 reportParseError("expected identifier after .set");
2037
2038 if (getLexer().isNot(AsmToken::Comma))
2039 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002040 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002041
Jack Carter02593002013-05-28 22:21:05 +00002042 if (getLexer().is(AsmToken::Dollar)) {
2043 MCSymbol *Symbol;
2044 SMLoc DollarLoc = getLexer().getLoc();
2045 // Consume the dollar sign, and check for a following identifier.
2046 Parser.Lex();
2047 // We have a '$' followed by something, make sure they are adjacent.
2048 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2049 return true;
2050 StringRef Res = StringRef(DollarLoc.getPointer(),
2051 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2052 Symbol = getContext().GetOrCreateSymbol(Res);
2053 Parser.Lex();
2054 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
2055 getContext());
2056 } else if (Parser.parseExpression(Value))
2057 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002058
Jack Carterd0bd6422013-04-18 00:41:53 +00002059 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002060 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002061 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002062 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002063 Sym = getContext().GetOrCreateSymbol(Name);
2064 Sym->setVariableValue(Value);
2065
2066 return false;
2067}
Jack Carterd0bd6422013-04-18 00:41:53 +00002068
Jack Carter0b744b32012-10-04 02:29:46 +00002069bool MipsAsmParser::parseDirectiveSet() {
2070
Jack Carterd0bd6422013-04-18 00:41:53 +00002071 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002072 const AsmToken &Tok = Parser.getTok();
2073
2074 if (Tok.getString() == "noat") {
2075 return parseSetNoAtDirective();
2076 } else if (Tok.getString() == "at") {
2077 return parseSetAtDirective();
2078 } else if (Tok.getString() == "reorder") {
2079 return parseSetReorderDirective();
2080 } else if (Tok.getString() == "noreorder") {
2081 return parseSetNoReorderDirective();
2082 } else if (Tok.getString() == "macro") {
2083 return parseSetMacroDirective();
2084 } else if (Tok.getString() == "nomacro") {
2085 return parseSetNoMacroDirective();
2086 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002087 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002088 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002089 return false;
2090 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002091 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002092 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002093 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002094 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002095 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002096 parseSetAssignment();
2097 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002098 }
Jack Carter07c818d2013-01-25 01:31:34 +00002099
Jack Carter0b744b32012-10-04 02:29:46 +00002100 return true;
2101}
2102
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002103bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2104 MCAsmParser &Parser = getParser();
2105 StringRef Name;
2106 if (Parser.parseIdentifier(Name))
2107 reportParseError("expected identifier");
2108
2109 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2110 if (getLexer().isNot(AsmToken::Comma))
2111 return TokError("unexpected token");
2112 Lex();
2113
2114 int64_t Flags = 0;
2115 if (Parser.parseAbsoluteExpression(Flags))
2116 return TokError("unexpected token");
2117
2118 Parser.getStreamer().emitMipsHackSTOCG(Sym, Flags);
2119 return false;
2120}
2121
2122bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2123 int64_t Flags = 0;
2124 if (Parser.parseAbsoluteExpression(Flags))
2125 return TokError("unexpected token");
2126
2127 Parser.getStreamer().emitMipsHackELFFlags(Flags);
2128 return false;
2129}
2130
Jack Carter07c818d2013-01-25 01:31:34 +00002131/// parseDirectiveWord
2132/// ::= .word [ expression (, expression)* ]
2133bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2135 for (;;) {
2136 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002137 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002138 return true;
2139
2140 getParser().getStreamer().EmitValue(Value, Size);
2141
2142 if (getLexer().is(AsmToken::EndOfStatement))
2143 break;
2144
2145 // FIXME: Improve diagnostic.
2146 if (getLexer().isNot(AsmToken::Comma))
2147 return Error(L, "unexpected token in directive");
2148 Parser.Lex();
2149 }
2150 }
2151
2152 Parser.Lex();
2153 return false;
2154}
2155
Jack Carter0b744b32012-10-04 02:29:46 +00002156bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00002157
Jack Carter07c818d2013-01-25 01:31:34 +00002158 StringRef IDVal = DirectiveID.getString();
2159
Jack Carterd0bd6422013-04-18 00:41:53 +00002160 if (IDVal == ".ent") {
2161 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002162 Parser.Lex();
2163 return false;
2164 }
2165
Jack Carter07c818d2013-01-25 01:31:34 +00002166 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002167 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002168 Parser.Lex();
2169 return false;
2170 }
2171
Jack Carter07c818d2013-01-25 01:31:34 +00002172 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002173 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002174 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002175 return false;
2176 }
2177
Jack Carter07c818d2013-01-25 01:31:34 +00002178 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002179 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002180 }
2181
Jack Carter07c818d2013-01-25 01:31:34 +00002182 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002183 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002184 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002185 return false;
2186 }
2187
Jack Carter07c818d2013-01-25 01:31:34 +00002188 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002189 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002190 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002191 return false;
2192 }
2193
Jack Carter07c818d2013-01-25 01:31:34 +00002194 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002195 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002196 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002197 return false;
2198 }
2199
Jack Carter07c818d2013-01-25 01:31:34 +00002200 if (IDVal == ".word") {
2201 parseDirectiveWord(4, DirectiveID.getLoc());
2202 return false;
2203 }
2204
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002205 if (IDVal == ".mips_hack_stocg")
2206 return parseDirectiveMipsHackStocg();
2207
2208 if (IDVal == ".mips_hack_elf_flags")
2209 return parseDirectiveMipsHackELFFlags();
2210
Rafael Espindola870c4e92012-01-11 03:56:41 +00002211 return true;
2212}
2213
Rafael Espindola870c4e92012-01-11 03:56:41 +00002214extern "C" void LLVMInitializeMipsAsmParser() {
2215 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2216 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2217 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2218 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2219}
Jack Carterb4dbc172012-09-05 23:34:03 +00002220
2221#define GET_REGISTER_MATCHER
2222#define GET_MATCHER_IMPLEMENTATION
2223#include "MipsGenAsmMatcher.inc"