blob: 447e7dc6e1c449a1d270b820c35219c52c259c7b [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();
183
184 bool parseSetAtDirective();
185 bool parseSetNoAtDirective();
186 bool parseSetMacroDirective();
187 bool parseSetNoMacroDirective();
188 bool parseSetReorderDirective();
189 bool parseSetNoReorderDirective();
190
Jack Carterd76b2372013-03-21 21:44:16 +0000191 bool parseSetAssignment();
192
Jack Carter07c818d2013-01-25 01:31:34 +0000193 bool parseDirectiveWord(unsigned Size, SMLoc L);
194
Jack Carterdc1e35d2012-09-06 20:00:02 +0000195 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000196
Jack Carterb4dbc172012-09-05 23:34:03 +0000197 bool isMips64() const {
198 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
199 }
200
Jack Cartera63b16a2012-09-07 00:23:42 +0000201 bool isFP64() const {
202 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
203 }
204
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000205 bool isN64() const {
206 return STI.getFeatureBits() & Mips::FeatureN64;
207 }
208
Jack Carter873c7242013-01-12 01:03:14 +0000209 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000210
Jack Carter1ac53222013-02-20 23:11:17 +0000211 int matchCPURegisterName(StringRef Symbol);
212
Jack Carter873c7242013-01-12 01:03:14 +0000213 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000214
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000215 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000216
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000217 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000218
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000219 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000220
Jack Carter5dc8ac92013-09-25 23:50:44 +0000221 int matchMSA128RegisterName(StringRef Name);
222
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000223 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000224
Jack Carterd0bd6422013-04-18 00:41:53 +0000225 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000226
Jack Carter1ac53222013-02-20 23:11:17 +0000227 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000228
229 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
230 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000231public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000232 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
233 const MCInstrInfo &MII)
234 : MCTargetAsmParser(), STI(sti), Parser(parser),
235 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000236 // Initialize the set of available features.
237 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000238 }
239
Jack Carterb4dbc172012-09-05 23:34:03 +0000240 MCAsmParser &getParser() const { return Parser; }
241 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
242
Rafael Espindola870c4e92012-01-11 03:56:41 +0000243};
244}
245
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000246namespace {
247
248/// MipsOperand - Instances of this class represent a parsed Mips machine
249/// instruction.
250class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000251
Jack Carter873c7242013-01-12 01:03:14 +0000252public:
253 enum RegisterKind {
254 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000255 Kind_GPR32,
256 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000257 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000258 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000259 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000260 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000261 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000262 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000263 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000264 Kind_ACC64DSP,
265 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000266 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000267 Kind_COP2,
268 Kind_MSA128BRegs,
269 Kind_MSA128HRegs,
270 Kind_MSA128WRegs,
271 Kind_MSA128DRegs
Jack Carter873c7242013-01-12 01:03:14 +0000272 };
273
274private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000275 enum KindTy {
276 k_CondCode,
277 k_CoprocNum,
278 k_Immediate,
279 k_Memory,
280 k_PostIndexRegister,
281 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000282 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000283 k_Token
284 } Kind;
285
286 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000287
Eric Christopher8996c5d2013-03-15 00:42:55 +0000288 struct Token {
289 const char *Data;
290 unsigned Length;
291 };
292
293 struct RegOp {
294 unsigned RegNum;
295 RegisterKind Kind;
296 };
297
298 struct ImmOp {
299 const MCExpr *Val;
300 };
301
302 struct MemOp {
303 unsigned Base;
304 const MCExpr *Off;
305 };
306
Jack Carterb4dbc172012-09-05 23:34:03 +0000307 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000308 struct Token Tok;
309 struct RegOp Reg;
310 struct ImmOp Imm;
311 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000312 };
313
314 SMLoc StartLoc, EndLoc;
315
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000316public:
317 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000318 assert(N == 1 && "Invalid number of operands!");
319 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000320 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000321
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000322 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
323 assert(N == 1 && "Invalid number of operands!");
324 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
325 }
326
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000327 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000328 // Add as immediate when possible. Null MCExpr = 0.
329 if (Expr == 0)
330 Inst.addOperand(MCOperand::CreateImm(0));
331 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
332 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
333 else
334 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000335 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000336
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000337 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000338 assert(N == 1 && "Invalid number of operands!");
339 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000340 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000341 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000342
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000343 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000344 assert(N == 2 && "Invalid number of operands!");
345
346 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
347
348 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000349 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000350 }
351
352 bool isReg() const { return Kind == k_Register; }
353 bool isImm() const { return Kind == k_Immediate; }
354 bool isToken() const { return Kind == k_Token; }
355 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000356 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000357 bool isInvNum() const { return Kind == k_Immediate; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000358
359 StringRef getToken() const {
360 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000361 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000362 }
363
364 unsigned getReg() const {
365 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000366 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000367 }
368
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000369 unsigned getPtrReg() const {
370 assert((Kind == k_PtrReg) && "Invalid access!");
371 return Reg.RegNum;
372 }
373
Jack Carter873c7242013-01-12 01:03:14 +0000374 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000375 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000376 Reg.Kind = RegKind;
377 }
378
Jack Carterb4dbc172012-09-05 23:34:03 +0000379 const MCExpr *getImm() const {
380 assert((Kind == k_Immediate) && "Invalid access!");
381 return Imm.Val;
382 }
383
Jack Carterdc1e35d2012-09-06 20:00:02 +0000384 unsigned getMemBase() const {
385 assert((Kind == k_Memory) && "Invalid access!");
386 return Mem.Base;
387 }
388
389 const MCExpr *getMemOff() const {
390 assert((Kind == k_Memory) && "Invalid access!");
391 return Mem.Off;
392 }
393
Jack Carterb4dbc172012-09-05 23:34:03 +0000394 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
395 MipsOperand *Op = new MipsOperand(k_Token);
396 Op->Tok.Data = Str.data();
397 Op->Tok.Length = Str.size();
398 Op->StartLoc = S;
399 Op->EndLoc = S;
400 return Op;
401 }
402
403 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
404 MipsOperand *Op = new MipsOperand(k_Register);
405 Op->Reg.RegNum = RegNum;
406 Op->StartLoc = S;
407 Op->EndLoc = E;
408 return Op;
409 }
410
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000411 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
412 MipsOperand *Op = new MipsOperand(k_PtrReg);
413 Op->Reg.RegNum = RegNum;
414 Op->StartLoc = S;
415 Op->EndLoc = E;
416 return Op;
417 }
418
Jack Carterb4dbc172012-09-05 23:34:03 +0000419 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
420 MipsOperand *Op = new MipsOperand(k_Immediate);
421 Op->Imm.Val = Val;
422 Op->StartLoc = S;
423 Op->EndLoc = E;
424 return Op;
425 }
426
Jack Carterdc1e35d2012-09-06 20:00:02 +0000427 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
428 SMLoc S, SMLoc E) {
429 MipsOperand *Op = new MipsOperand(k_Memory);
430 Op->Mem.Base = Base;
431 Op->Mem.Off = Off;
432 Op->StartLoc = S;
433 Op->EndLoc = E;
434 return Op;
435 }
436
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000437 bool isGPR32Asm() const {
438 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000439 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000440 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000441 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
442 }
443
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000444 bool isGPR64Asm() const {
445 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000446 }
Jack Carter873c7242013-01-12 01:03:14 +0000447
448 bool isHWRegsAsm() const {
449 assert((Kind == k_Register) && "Invalid access!");
450 return Reg.Kind == Kind_HWRegs;
451 }
Jack Carter873c7242013-01-12 01:03:14 +0000452
Jack Carter873c7242013-01-12 01:03:14 +0000453 bool isCCRAsm() const {
454 assert((Kind == k_Register) && "Invalid access!");
455 return Reg.Kind == Kind_CCRRegs;
456 }
457
Vladimir Medic233dd512013-06-24 10:05:34 +0000458 bool isAFGR64Asm() const {
459 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
460 }
461
462 bool isFGR64Asm() const {
463 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
464 }
465
466 bool isFGR32Asm() const {
467 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
468 }
469
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000470 bool isFGRH32Asm() const {
471 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
472 }
473
Vladimir Medic643b3982013-07-30 10:12:14 +0000474 bool isFCCRegsAsm() const {
475 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
476 }
477
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000478 bool isACC64DSPAsm() const {
479 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000480 }
481
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000482 bool isLO32DSPAsm() const {
483 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
484 }
485
486 bool isHI32DSPAsm() const {
487 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
488 }
489
Vladimir Medic05bcde62013-09-16 10:29:42 +0000490 bool isCOP2Asm() const {
491 return Kind == k_Register && Reg.Kind == Kind_COP2;
492 }
493
Jack Carter5dc8ac92013-09-25 23:50:44 +0000494 bool isMSA128BAsm() const {
495 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
496 }
497
498 bool isMSA128HAsm() const {
499 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
500 }
501
502 bool isMSA128WAsm() const {
503 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
504 }
505
506 bool isMSA128DAsm() const {
507 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
508 }
509
Jack Carterb4dbc172012-09-05 23:34:03 +0000510 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000511 SMLoc getStartLoc() const {
512 return StartLoc;
513 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000514 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000515 SMLoc getEndLoc() const {
516 return EndLoc;
517 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000518
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000519 virtual void print(raw_ostream &OS) const {
520 llvm_unreachable("unimplemented!");
521 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000522}; // class MipsOperand
523} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000524
Jack Carter9e65aa32013-03-22 00:05:30 +0000525namespace llvm {
526extern const MCInstrDesc MipsInsts[];
527}
528static const MCInstrDesc &getInstDesc(unsigned Opcode) {
529 return MipsInsts[Opcode];
530}
531
532bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000533 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000534 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
535 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000536 if (MCID.hasDelaySlot() && Options.isReorder()) {
537 // If this instruction has a delay slot and .set reorder is active,
538 // emit a NOP after it.
539 Instructions.push_back(Inst);
540 MCInst NopInst;
541 NopInst.setOpcode(Mips::SLL);
542 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
543 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
544 NopInst.addOperand(MCOperand::CreateImm(0));
545 Instructions.push_back(NopInst);
546 return false;
547 }
548
Jack Carter9e65aa32013-03-22 00:05:30 +0000549 if (MCID.mayLoad() || MCID.mayStore()) {
550 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000551 // reference or immediate we may have to expand instructions.
552 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000553 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000554 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
555 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000556 MCOperand &Op = Inst.getOperand(i);
557 if (Op.isImm()) {
558 int MemOffset = Op.getImm();
559 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000560 // Offset can't exceed 16bit value.
561 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000562 return false;
563 }
564 } else if (Op.isExpr()) {
565 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000566 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000567 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000568 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000569 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000570 // Expand symbol.
571 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000572 return false;
573 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000574 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000575 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000576 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000577 }
578 }
579 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000580 } // for
581 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000582
583 if (needsExpansion(Inst))
584 expandInstruction(Inst, IDLoc, Instructions);
585 else
586 Instructions.push_back(Inst);
587
588 return false;
589}
590
Jack Carter30a59822012-10-04 04:03:53 +0000591bool MipsAsmParser::needsExpansion(MCInst &Inst) {
592
Jack Carterd0bd6422013-04-18 00:41:53 +0000593 switch (Inst.getOpcode()) {
594 case Mips::LoadImm32Reg:
595 case Mips::LoadAddr32Imm:
596 case Mips::LoadAddr32Reg:
597 return true;
598 default:
599 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000600 }
601}
Jack Carter92995f12012-10-06 00:53:28 +0000602
Jack Carter30a59822012-10-04 04:03:53 +0000603void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000604 SmallVectorImpl<MCInst> &Instructions) {
605 switch (Inst.getOpcode()) {
606 case Mips::LoadImm32Reg:
607 return expandLoadImm(Inst, IDLoc, Instructions);
608 case Mips::LoadAddr32Imm:
609 return expandLoadAddressImm(Inst, IDLoc, Instructions);
610 case Mips::LoadAddr32Reg:
611 return expandLoadAddressReg(Inst, IDLoc, Instructions);
612 }
Jack Carter30a59822012-10-04 04:03:53 +0000613}
Jack Carter92995f12012-10-06 00:53:28 +0000614
Jack Carter30a59822012-10-04 04:03:53 +0000615void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000616 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000617 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000618 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000619 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000620 const MCOperand &RegOp = Inst.getOperand(0);
621 assert(RegOp.isReg() && "expected register operand kind");
622
623 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000624 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000625 if (0 <= ImmValue && ImmValue <= 65535) {
626 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000627 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000628 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000629 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000630 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000631 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000632 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000633 } else if (ImmValue < 0 && ImmValue >= -32768) {
634 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000635 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000636 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000637 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000638 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000639 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000640 Instructions.push_back(tmpInst);
641 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000642 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000643 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000644 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000645 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000646 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
647 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000648 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000649 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000650 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000651 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
652 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
653 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
654 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000655 Instructions.push_back(tmpInst);
656 }
657}
Jack Carter92995f12012-10-06 00:53:28 +0000658
Jack Carter543fdf82012-10-09 23:29:45 +0000659void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000660 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000661 MCInst tmpInst;
662 const MCOperand &ImmOp = Inst.getOperand(2);
663 assert(ImmOp.isImm() && "expected immediate operand kind");
664 const MCOperand &SrcRegOp = Inst.getOperand(1);
665 assert(SrcRegOp.isReg() && "expected register operand kind");
666 const MCOperand &DstRegOp = Inst.getOperand(0);
667 assert(DstRegOp.isReg() && "expected register operand kind");
668 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000669 if (-32768 <= ImmValue && ImmValue <= 65535) {
670 // For -32768 <= j <= 65535.
671 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000672 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000673 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
674 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
675 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
676 Instructions.push_back(tmpInst);
677 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000678 // For any other value of j that is representable as a 32-bit integer.
679 // la d,j(s) => lui d,hi16(j)
680 // ori d,d,lo16(j)
681 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000682 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000683 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
684 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
685 Instructions.push_back(tmpInst);
686 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000687 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000688 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
689 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
690 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
691 Instructions.push_back(tmpInst);
692 tmpInst.clear();
693 tmpInst.setOpcode(Mips::ADDu);
694 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
695 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
696 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
697 Instructions.push_back(tmpInst);
698 }
699}
700
701void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000702 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000703 MCInst tmpInst;
704 const MCOperand &ImmOp = Inst.getOperand(1);
705 assert(ImmOp.isImm() && "expected immediate operand kind");
706 const MCOperand &RegOp = Inst.getOperand(0);
707 assert(RegOp.isReg() && "expected register operand kind");
708 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000709 if (-32768 <= ImmValue && ImmValue <= 65535) {
710 // For -32768 <= j <= 65535.
711 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000712 tmpInst.setOpcode(Mips::ADDiu);
713 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000714 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000715 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
716 Instructions.push_back(tmpInst);
717 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000718 // For any other value of j that is representable as a 32-bit integer.
719 // la d,j => lui d,hi16(j)
720 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000721 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000722 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
723 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
724 Instructions.push_back(tmpInst);
725 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000726 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000727 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
728 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
729 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
730 Instructions.push_back(tmpInst);
731 }
732}
733
Jack Carter9e65aa32013-03-22 00:05:30 +0000734void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000735 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000736 const MCSymbolRefExpr *SR;
737 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000738 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000739 const MCExpr *ExprOffset;
740 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000741 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
742 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000743 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000744 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
745 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000746 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000747 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
748 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000749 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000750 if (isImmOpnd) {
751 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
752 ImmOffset = Inst.getOperand(2).getImm();
753 LoOffset = ImmOffset & 0x0000ffff;
754 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000755 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000756 if (LoOffset & 0x8000)
757 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000758 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000759 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000760 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000761 TempInst.setLoc(IDLoc);
762 // 1st instruction in expansion is LUi. For load instruction we can use
763 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000764 // but for stores we must use $at.
765 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000766 TempInst.setOpcode(Mips::LUi);
767 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
768 if (isImmOpnd)
769 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
770 else {
771 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
772 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000773 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
774 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
775 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000776 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000777 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000778 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000779 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000780 }
781 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000782 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000783 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000784 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000785 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000786 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000787 TempInst.setOpcode(Mips::ADDu);
788 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
789 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
790 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
791 Instructions.push_back(TempInst);
792 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000793 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000794 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000795 TempInst.setOpcode(Inst.getOpcode());
796 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
797 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
798 if (isImmOpnd)
799 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
800 else {
801 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000802 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
803 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
804 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000805 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000806 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000807 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000808 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000809 }
810 }
811 Instructions.push_back(TempInst);
812 TempInst.clear();
813}
814
Rafael Espindola870c4e92012-01-11 03:56:41 +0000815bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000816MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000817 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000818 MCStreamer &Out, unsigned &ErrorInfo,
819 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000820 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000821 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000822 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000823 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000824
825 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000826 default:
827 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000828 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000829 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000830 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000831 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000832 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000833 return false;
834 }
835 case Match_MissingFeature:
836 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
837 return true;
838 case Match_InvalidOperand: {
839 SMLoc ErrorLoc = IDLoc;
840 if (ErrorInfo != ~0U) {
841 if (ErrorInfo >= Operands.size())
842 return Error(IDLoc, "too few operands for instruction");
843
Jack Carterd0bd6422013-04-18 00:41:53 +0000844 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
845 if (ErrorLoc == SMLoc())
846 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000847 }
848
849 return Error(ErrorLoc, "invalid operand for instruction");
850 }
851 case Match_MnemonicFail:
852 return Error(IDLoc, "invalid instruction");
853 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000854 return true;
855}
856
Jack Carter1ac53222013-02-20 23:11:17 +0000857int MipsAsmParser::matchCPURegisterName(StringRef Name) {
858 int CC;
859
860 if (Name == "at")
861 return getATReg();
862
863 CC = StringSwitch<unsigned>(Name)
864 .Case("zero", 0)
865 .Case("a0", 4)
866 .Case("a1", 5)
867 .Case("a2", 6)
868 .Case("a3", 7)
869 .Case("v0", 2)
870 .Case("v1", 3)
871 .Case("s0", 16)
872 .Case("s1", 17)
873 .Case("s2", 18)
874 .Case("s3", 19)
875 .Case("s4", 20)
876 .Case("s5", 21)
877 .Case("s6", 22)
878 .Case("s7", 23)
879 .Case("k0", 26)
880 .Case("k1", 27)
881 .Case("sp", 29)
882 .Case("fp", 30)
883 .Case("gp", 28)
884 .Case("ra", 31)
885 .Case("t0", 8)
886 .Case("t1", 9)
887 .Case("t2", 10)
888 .Case("t3", 11)
889 .Case("t4", 12)
890 .Case("t5", 13)
891 .Case("t6", 14)
892 .Case("t7", 15)
893 .Case("t8", 24)
894 .Case("t9", 25)
895 .Default(-1);
896
Jack Carterd0bd6422013-04-18 00:41:53 +0000897 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000898 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
899 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000900 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000901 CC += 4;
902
903 if (CC == -1 && isMips64())
904 CC = StringSwitch<unsigned>(Name)
905 .Case("a4", 8)
906 .Case("a5", 9)
907 .Case("a6", 10)
908 .Case("a7", 11)
909 .Case("kt0", 26)
910 .Case("kt1", 27)
911 .Case("s8", 30)
912 .Default(-1);
913
914 return CC;
915}
Jack Carterd0bd6422013-04-18 00:41:53 +0000916
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000917int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000918
Jack Cartera63b16a2012-09-07 00:23:42 +0000919 if (Name[0] == 'f') {
920 StringRef NumString = Name.substr(1);
921 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000922 if (NumString.getAsInteger(10, IntVal))
923 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000924 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000925 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000926 return IntVal;
927 }
928 return -1;
929}
Jack Cartera63b16a2012-09-07 00:23:42 +0000930
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000931int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
932
933 if (Name.startswith("fcc")) {
934 StringRef NumString = Name.substr(3);
935 unsigned IntVal;
936 if (NumString.getAsInteger(10, IntVal))
937 return -1; // This is not an integer.
938 if (IntVal > 7) // There are only 8 fcc registers.
939 return -1;
940 return IntVal;
941 }
942 return -1;
943}
944
945int MipsAsmParser::matchACRegisterName(StringRef Name) {
946
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000947 if (Name.startswith("ac")) {
948 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000949 unsigned IntVal;
950 if (NumString.getAsInteger(10, IntVal))
951 return -1; // This is not an integer.
952 if (IntVal > 3) // There are only 3 acc registers.
953 return -1;
954 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000955 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000956 return -1;
957}
Jack Carterd0bd6422013-04-18 00:41:53 +0000958
Jack Carter5dc8ac92013-09-25 23:50:44 +0000959int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
960 unsigned IntVal;
961
962 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
963 return -1;
964
965 if (IntVal > 31)
966 return -1;
967
968 return IntVal;
969}
970
Vladimir Medic8cd17102013-06-20 11:21:49 +0000971int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
972
Vladimir Medic8cd17102013-06-20 11:21:49 +0000973 int CC;
974 CC = matchCPURegisterName(Name);
975 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000976 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
977 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000978 CC = matchFPURegisterName(Name);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000979 //TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +0000980 if (CC != -1)
981 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
982 : Mips::FGR32RegClassID);
983 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000984}
985
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000986int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000987
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000988 switch (RegKind) {
989 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
990 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
991 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
992 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000993 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000994 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
995 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
996 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
997 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
998 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
Jack Carter5dc8ac92013-09-25 23:50:44 +0000999 case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
1000 case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
1001 case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
1002 case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001003 default :return -1;
1004 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001005
Jack Cartera63b16a2012-09-07 00:23:42 +00001006}
Jack Carterb4dbc172012-09-05 23:34:03 +00001007
Jack Carter0b744b32012-10-04 02:29:46 +00001008bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1009 if (Reg > 31)
1010 return false;
1011
1012 aTReg = Reg;
1013 return true;
1014}
1015
Jack Carter1ac53222013-02-20 23:11:17 +00001016int MipsAsmParser::getATReg() {
1017 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +00001018}
1019
Jack Carterd0bd6422013-04-18 00:41:53 +00001020unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001021 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001022}
1023
Jack Carter873c7242013-01-12 01:03:14 +00001024int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001025 if (RegNum >
1026 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001027 return -1;
1028
Jack Carter873c7242013-01-12 01:03:14 +00001029 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001030}
1031
Jack Carter873c7242013-01-12 01:03:14 +00001032int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001033 const AsmToken &Tok = Parser.getTok();
1034 int RegNum = -1;
1035
1036 if (Tok.is(AsmToken::Identifier)) {
1037 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001038 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001039 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001040 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001041 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001042 return RegNum;
1043}
1044
Jack Carterd0bd6422013-04-18 00:41:53 +00001045bool MipsAsmParser::tryParseRegisterOperand(
1046 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001047
1048 SMLoc S = Parser.getTok().getLoc();
1049 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001050
Jack Carter873c7242013-01-12 01:03:14 +00001051 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001052 if (RegNo == -1)
1053 return true;
1054
Jack Carter873c7242013-01-12 01:03:14 +00001055 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +00001056 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001057 Parser.Lex(); // Eat register token.
1058 return false;
1059}
1060
1061bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1062 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001063 // Check if the current operand has a custom associated parser, if so, try to
1064 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001065 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1066 if (ResTy == MatchOperand_Success)
1067 return false;
1068 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1069 // there was a match, but an error occurred, in which case, just return that
1070 // the operand parsing failed.
1071 if (ResTy == MatchOperand_ParseFail)
1072 return true;
1073
1074 switch (getLexer().getKind()) {
1075 default:
1076 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1077 return true;
1078 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001079 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001080 SMLoc S = Parser.getTok().getLoc();
1081 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001082 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001083 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001084 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001085 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001086 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001087 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001088 if (getLexer().isNot(AsmToken::Dollar))
1089 return true;
1090
Jack Carterd0bd6422013-04-18 00:41:53 +00001091 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001092 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001093 return true;
1094
1095 if (!getLexer().is(AsmToken::RParen))
1096 return true;
1097
1098 S = Parser.getTok().getLoc();
1099 Operands.push_back(MipsOperand::CreateToken(")", S));
1100 Parser.Lex();
1101 }
1102 return false;
1103 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001104 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001105 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001106 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001107 return true;
1108
Jack Carter873c7242013-01-12 01:03:14 +00001109 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001110
Benjamin Kramerfa530572012-09-07 09:47:42 +00001111 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001112
Jack Carterd0bd6422013-04-18 00:41:53 +00001113 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001114 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001115 getContext());
1116
1117 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1118 return false;
1119 }
1120 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001121 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001122 // we need to assigne the propper RegisterKind.
1123 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1124 return false;
1125 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001126 case AsmToken::LParen:
1127 case AsmToken::Minus:
1128 case AsmToken::Plus:
1129 case AsmToken::Integer:
1130 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001131 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001132 const MCExpr *IdVal;
1133 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001134 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001135 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001136 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001137 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1138 return false;
1139 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001140 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001141 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001142 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001143 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001144 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001145 return true;
1146
Jack Carter873c7242013-01-12 01:03:14 +00001147 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1148
Jack Carterdc1e35d2012-09-06 20:00:02 +00001149 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1150 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001151 } // case AsmToken::Percent
1152 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001153 return true;
1154}
1155
Jack Carterb5cf5902013-04-17 00:18:04 +00001156const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1157 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001158 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001159 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001160 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001161 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001162 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001163 short Val = MCE->getValue();
1164 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001165 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001166 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001167 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001168 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001169 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001170 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001171 if (LoSign)
1172 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001173 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001174 } else {
1175 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001176 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001177 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001178 }
1179
Jack Carterb5cf5902013-04-17 00:18:04 +00001180 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001181 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001182 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001183 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001184 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001185 return Res;
1186 }
1187
1188 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001189 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1190 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001191 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1192 return Res;
1193 }
1194
1195 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001196 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1197 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1198 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001199 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001200 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001201 return Expr;
1202}
1203
1204bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1205
1206 switch (Expr->getKind()) {
1207 case MCExpr::Constant:
1208 return true;
1209 case MCExpr::SymbolRef:
1210 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1211 case MCExpr::Binary:
1212 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1213 if (!isEvaluated(BE->getLHS()))
1214 return false;
1215 return isEvaluated(BE->getRHS());
1216 }
1217 case MCExpr::Unary:
1218 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1219 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001220 return false;
1221 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001222 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001223}
Jack Carterd0bd6422013-04-18 00:41:53 +00001224
Jack Carterb5cf5902013-04-17 00:18:04 +00001225bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001226 Parser.Lex(); // Eat the % token.
1227 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001228 if (Tok.isNot(AsmToken::Identifier))
1229 return true;
1230
1231 std::string Str = Tok.getIdentifier().str();
1232
Jack Carterd0bd6422013-04-18 00:41:53 +00001233 Parser.Lex(); // Eat the identifier.
1234 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001235 const MCExpr *IdVal;
1236 SMLoc EndLoc;
1237
1238 if (getLexer().getKind() == AsmToken::LParen) {
1239 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001240 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001241 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001242 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001243 const AsmToken &nextTok = Parser.getTok();
1244 if (nextTok.isNot(AsmToken::Identifier))
1245 return true;
1246 Str += "(%";
1247 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001248 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001249 if (getLexer().getKind() != AsmToken::LParen)
1250 return true;
1251 } else
1252 break;
1253 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001254 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001255 return true;
1256
1257 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001258 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001259
1260 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001261 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001262
Jack Carterd0bd6422013-04-18 00:41:53 +00001263 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001264 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001265}
1266
Jack Carterb4dbc172012-09-05 23:34:03 +00001267bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1268 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001269 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001270 RegNo = tryParseRegister(isMips64());
1271 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001272 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001273}
1274
Jack Carterb5cf5902013-04-17 00:18:04 +00001275bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001276 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001277 bool Result = true;
1278
1279 while (getLexer().getKind() == AsmToken::LParen)
1280 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001281
Jack Carterd0bd6422013-04-18 00:41:53 +00001282 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001283 default:
1284 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001285 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001286 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001287 case AsmToken::Integer:
1288 case AsmToken::Minus:
1289 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001290 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001291 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001292 else
1293 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001294 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001295 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001296 break;
Jack Carter873c7242013-01-12 01:03:14 +00001297 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001298 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001299 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001300 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001301}
1302
Jack Carterb4dbc172012-09-05 23:34:03 +00001303MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001304 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001305
1306 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001307 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001308 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001309 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001310 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001311 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001312
Jack Carterb5cf5902013-04-17 00:18:04 +00001313 if (getLexer().getKind() == AsmToken::LParen) {
1314 Parser.Lex();
1315 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001316 }
1317
Jack Carterb5cf5902013-04-17 00:18:04 +00001318 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001319 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001320 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001321
Jack Carterd0bd6422013-04-18 00:41:53 +00001322 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001323 if (Tok.isNot(AsmToken::LParen)) {
1324 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1325 if (Mnemonic->getToken() == "la") {
1326 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001327 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001328 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1329 return MatchOperand_Success;
1330 }
1331 if (Tok.is(AsmToken::EndOfStatement)) {
1332 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001333 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001334
Jack Carterd0bd6422013-04-18 00:41:53 +00001335 // Zero register assumed, add a memory operand with ZERO as its base.
1336 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1337 : Mips::ZERO,
1338 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001339 return MatchOperand_Success;
1340 }
1341 Error(Parser.getTok().getLoc(), "'(' expected");
1342 return MatchOperand_ParseFail;
1343 }
1344
Jack Carterd0bd6422013-04-18 00:41:53 +00001345 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001346 }
1347
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001348 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1349 (int) MipsOperand::Kind_GPR32);
1350 if (Res != MatchOperand_Success)
1351 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001352
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001353 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001354 Error(Parser.getTok().getLoc(), "')' expected");
1355 return MatchOperand_ParseFail;
1356 }
1357
Jack Carter873c7242013-01-12 01:03:14 +00001358 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1359
Jack Carterd0bd6422013-04-18 00:41:53 +00001360 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001361
1362 if (IdVal == 0)
1363 IdVal = MCConstantExpr::Create(0, getContext());
1364
Jack Carterd0bd6422013-04-18 00:41:53 +00001365 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001366 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1367 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001368 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001369 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001370 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001371 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1372 int64_t Imm;
1373 if (IdVal->EvaluateAsAbsolute(Imm))
1374 IdVal = MCConstantExpr::Create(Imm, getContext());
1375 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1376 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1377 getContext());
1378 }
1379
Jack Carterdc1e35d2012-09-06 20:00:02 +00001380 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1381 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001382 return MatchOperand_Success;
1383}
1384
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001385bool
1386MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1387 int RegKind) {
1388 // If the first token is not '$' we have an error.
1389 if (Parser.getTok().isNot(AsmToken::Dollar))
1390 return false;
1391
1392 SMLoc S = Parser.getTok().getLoc();
1393 Parser.Lex();
1394 AsmToken::TokenKind TkKind = getLexer().getKind();
1395 int Reg;
1396
1397 if (TkKind == AsmToken::Integer) {
1398 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1399 regKindToRegClass(RegKind));
1400 if (Reg == -1)
1401 return false;
1402 } else if (TkKind == AsmToken::Identifier) {
1403 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1404 return false;
1405 Reg = getReg(regKindToRegClass(RegKind), Reg);
1406 } else {
1407 return false;
1408 }
1409
1410 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1411 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1412 Operands.push_back(Op);
1413 Parser.Lex();
1414 return true;
1415}
1416
1417MipsAsmParser::OperandMatchResultTy
1418MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1419 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1420 MipsOperand::Kind_GPR32;
1421
1422 // Parse index register.
1423 if (!parsePtrReg(Operands, RegKind))
1424 return MatchOperand_NoMatch;
1425
1426 // Parse '('.
1427 if (Parser.getTok().isNot(AsmToken::LParen))
1428 return MatchOperand_NoMatch;
1429
1430 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1431 Parser.Lex();
1432
1433 // Parse base register.
1434 if (!parsePtrReg(Operands, RegKind))
1435 return MatchOperand_NoMatch;
1436
1437 // Parse ')'.
1438 if (Parser.getTok().isNot(AsmToken::RParen))
1439 return MatchOperand_NoMatch;
1440
1441 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1442 Parser.Lex();
1443
1444 return MatchOperand_Success;
1445}
1446
Jack Carter873c7242013-01-12 01:03:14 +00001447MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001448MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1449 int RegKind) {
1450 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001451 if (getLexer().getKind() == AsmToken::Identifier
1452 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001453 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001454 return MatchOperand_Success;
1455 return MatchOperand_NoMatch;
1456 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001457 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001458 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001459 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001460 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001461 if (!hasConsumedDollar) {
1462 Parser.Lex(); // Eat the '$'
1463 hasConsumedDollar = true;
1464 }
1465 if (getLexer().getKind() == AsmToken::Identifier) {
1466 int RegNum = -1;
1467 std::string RegName = Parser.getTok().getString().lower();
1468 // Match register by name
1469 switch (RegKind) {
1470 case MipsOperand::Kind_GPR32:
1471 case MipsOperand::Kind_GPR64:
1472 RegNum = matchCPURegisterName(RegName);
1473 break;
1474 case MipsOperand::Kind_AFGR64Regs:
1475 case MipsOperand::Kind_FGR64Regs:
1476 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001477 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001478 RegNum = matchFPURegisterName(RegName);
1479 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1480 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001481 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1482 && !isFP64())
1483 if (RegNum != -1 && RegNum %2 != 0)
1484 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001485 break;
1486 case MipsOperand::Kind_FCCRegs:
1487 RegNum = matchFCCRegisterName(RegName);
1488 break;
1489 case MipsOperand::Kind_ACC64DSP:
1490 RegNum = matchACRegisterName(RegName);
1491 break;
1492 default: break; // No match, value is set to -1.
1493 }
1494 // No match found, return _NoMatch to give a chance to other round.
1495 if (RegNum < 0)
1496 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001497
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001498 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1499 if (RegVal == -1)
1500 return MatchOperand_NoMatch;
1501
1502 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1503 Parser.getTok().getLoc());
1504 Op->setRegKind(Kind);
1505 Operands.push_back(Op);
1506 hasConsumedDollar = false;
1507 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001508 return MatchOperand_Success;
1509 } else if (getLexer().getKind() == AsmToken::Integer) {
1510 unsigned RegNum = Parser.getTok().getIntVal();
1511 if (Kind == MipsOperand::Kind_HWRegs) {
1512 if (RegNum != 29)
1513 return MatchOperand_NoMatch;
1514 // Only hwreg 29 is supported, found at index 0.
1515 RegNum = 0;
1516 }
1517 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1518 if (Reg == -1)
1519 return MatchOperand_NoMatch;
1520 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1521 Op->setRegKind(Kind);
1522 Operands.push_back(Op);
1523 hasConsumedDollar = false;
1524 Parser.Lex(); // Eat the register number.
1525 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001526 && (getLexer().is(AsmToken::LParen))) {
1527 // Check if it is indexed addressing operand.
1528 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1529 Parser.Lex(); // Eat the parenthesis.
1530 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1531 return MatchOperand_NoMatch;
1532 if (getLexer().isNot(AsmToken::RParen))
1533 return MatchOperand_NoMatch;
1534 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1535 Parser.Lex();
1536 }
Jack Carter873c7242013-01-12 01:03:14 +00001537 return MatchOperand_Success;
1538 }
1539 return MatchOperand_NoMatch;
1540}
Vladimir Medic64828a12013-07-16 10:07:14 +00001541
Vladimir Medic8cd17102013-06-20 11:21:49 +00001542MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +00001543MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1544 int RegKind) {
1545 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1546 SMLoc S = Parser.getTok().getLoc();
1547 std::string RegName;
1548
1549 if (Parser.getTok().isNot(AsmToken::Dollar))
1550 return MatchOperand_NoMatch;
1551
1552 switch (RegKind) {
1553 default:
1554 return MatchOperand_ParseFail;
1555 case MipsOperand::Kind_MSA128BRegs:
1556 case MipsOperand::Kind_MSA128HRegs:
1557 case MipsOperand::Kind_MSA128WRegs:
1558 case MipsOperand::Kind_MSA128DRegs:
1559 break;
1560 }
1561
1562 Parser.Lex(); // Eat the '$'.
1563 if (getLexer().getKind() == AsmToken::Identifier)
1564 RegName = Parser.getTok().getString().lower();
1565 else
1566 return MatchOperand_ParseFail;
1567
1568 int RegNum = matchMSA128RegisterName(RegName);
1569
1570 if (RegNum < 0 || RegNum > 31)
1571 return MatchOperand_ParseFail;
1572
1573 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1574 if (RegVal == -1)
1575 return MatchOperand_ParseFail;
1576
1577 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1578 Parser.getTok().getLoc());
1579 Op->setRegKind(Kind);
1580 Operands.push_back(Op);
1581
1582 Parser.Lex(); // Eat the register identifier.
1583
1584 return MatchOperand_Success;
1585}
1586
1587MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001588MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001589
1590 if (!isMips64())
1591 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001592 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001593}
1594
1595MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001596MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1597 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001598}
Jack Carter873c7242013-01-12 01:03:14 +00001599
Vladimir Medic233dd512013-06-24 10:05:34 +00001600MipsAsmParser::OperandMatchResultTy
1601MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1602
1603 if (isFP64())
1604 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001605 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1606}
1607
1608MipsAsmParser::OperandMatchResultTy
1609MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1610 if (!isFP64())
1611 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001612 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1613}
1614
1615MipsAsmParser::OperandMatchResultTy
1616MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001617 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1618}
1619
Vladimir Medic643b3982013-07-30 10:12:14 +00001620MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001621MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1622 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1623}
1624
1625MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001626MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001627 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001628}
1629
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001630MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001631MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001632 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001633}
1634
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001635MipsAsmParser::OperandMatchResultTy
1636MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1637 // If the first token is not '$' we have an error.
1638 if (Parser.getTok().isNot(AsmToken::Dollar))
1639 return MatchOperand_NoMatch;
1640
1641 SMLoc S = Parser.getTok().getLoc();
1642 Parser.Lex(); // Eat the '$'
1643
1644 const AsmToken &Tok = Parser.getTok(); // Get next token.
1645
1646 if (Tok.isNot(AsmToken::Identifier))
1647 return MatchOperand_NoMatch;
1648
1649 if (!Tok.getIdentifier().startswith("ac"))
1650 return MatchOperand_NoMatch;
1651
1652 StringRef NumString = Tok.getIdentifier().substr(2);
1653
1654 unsigned IntVal;
1655 if (NumString.getAsInteger(10, IntVal))
1656 return MatchOperand_NoMatch;
1657
1658 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1659
1660 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1661 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1662 Operands.push_back(Op);
1663
1664 Parser.Lex(); // Eat the register number.
1665 return MatchOperand_Success;
1666}
1667
1668MipsAsmParser::OperandMatchResultTy
1669MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1670 // If the first token is not '$' we have an error.
1671 if (Parser.getTok().isNot(AsmToken::Dollar))
1672 return MatchOperand_NoMatch;
1673
1674 SMLoc S = Parser.getTok().getLoc();
1675 Parser.Lex(); // Eat the '$'
1676
1677 const AsmToken &Tok = Parser.getTok(); // Get next token.
1678
1679 if (Tok.isNot(AsmToken::Identifier))
1680 return MatchOperand_NoMatch;
1681
1682 if (!Tok.getIdentifier().startswith("ac"))
1683 return MatchOperand_NoMatch;
1684
1685 StringRef NumString = Tok.getIdentifier().substr(2);
1686
1687 unsigned IntVal;
1688 if (NumString.getAsInteger(10, IntVal))
1689 return MatchOperand_NoMatch;
1690
1691 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1692
1693 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1694 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1695 Operands.push_back(Op);
1696
1697 Parser.Lex(); // Eat the register number.
1698 return MatchOperand_Success;
1699}
1700
Vladimir Medic05bcde62013-09-16 10:29:42 +00001701MipsAsmParser::OperandMatchResultTy
1702MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1703 // If the first token is not '$' we have an error.
1704 if (Parser.getTok().isNot(AsmToken::Dollar))
1705 return MatchOperand_NoMatch;
1706
1707 SMLoc S = Parser.getTok().getLoc();
1708 Parser.Lex(); // Eat the '$'
1709
1710 const AsmToken &Tok = Parser.getTok(); // Get next token.
1711
1712 if (Tok.isNot(AsmToken::Integer))
1713 return MatchOperand_NoMatch;
1714
1715 unsigned IntVal = Tok.getIntVal();
1716
1717 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1718
1719 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1720 Op->setRegKind(MipsOperand::Kind_COP2);
1721 Operands.push_back(Op);
1722
1723 Parser.Lex(); // Eat the register number.
1724 return MatchOperand_Success;
1725}
1726
Jack Carter5dc8ac92013-09-25 23:50:44 +00001727MipsAsmParser::OperandMatchResultTy
1728MipsAsmParser::parseMSA128BRegs(
1729 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1730 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
1731}
1732
1733MipsAsmParser::OperandMatchResultTy
1734MipsAsmParser::parseMSA128HRegs(
1735 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1736 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
1737}
1738
1739MipsAsmParser::OperandMatchResultTy
1740MipsAsmParser::parseMSA128WRegs(
1741 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1742 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
1743}
1744
1745MipsAsmParser::OperandMatchResultTy
1746MipsAsmParser::parseMSA128DRegs(
1747 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1748 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
1749}
1750
Jack Carterd0bd6422013-04-18 00:41:53 +00001751bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001752 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001753
1754 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1755 if (Sym) {
1756 SMLoc S = Parser.getTok().getLoc();
1757 const MCExpr *Expr;
1758 if (Sym->isVariable())
1759 Expr = Sym->getVariableValue();
1760 else
1761 return false;
1762 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001763 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001764 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1765 const StringRef DefSymbol = Ref->getSymbol().getName();
1766 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001767 int RegNum = -1;
1768 APInt IntVal(32, -1);
1769 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1770 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001771 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001772 ? Mips::GPR64RegClassID
1773 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001774 else {
1775 // Lookup for the register with the corresponding name.
1776 switch (Kind) {
1777 case MipsOperand::Kind_AFGR64Regs:
1778 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001779 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001780 break;
1781 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001782 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001783 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001784 case MipsOperand::Kind_GPR64:
1785 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001786 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001787 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001788 break;
1789 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001790 if (RegNum > -1)
1791 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001792 }
Jack Carterd76b2372013-03-21 21:44:16 +00001793 if (RegNum > -1) {
1794 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001795 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1796 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001797 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001798 Operands.push_back(op);
1799 return true;
1800 }
1801 }
1802 } else if (Expr->getKind() == MCExpr::Constant) {
1803 Parser.Lex();
1804 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001805 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001806 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001807 Operands.push_back(op);
1808 return true;
1809 }
1810 }
1811 return false;
1812}
Jack Carterd0bd6422013-04-18 00:41:53 +00001813
Jack Carter873c7242013-01-12 01:03:14 +00001814MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001815MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001816 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001817}
1818
1819MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001820MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001821 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001822}
1823
Vladimir Medic2b953d02013-10-01 09:48:56 +00001824MipsAsmParser::OperandMatchResultTy
1825MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1826 const MCExpr *IdVal;
1827 // If the first token is '$' we may have register operand.
1828 if (Parser.getTok().is(AsmToken::Dollar))
1829 return MatchOperand_NoMatch;
1830 SMLoc S = Parser.getTok().getLoc();
1831 if (getParser().parseExpression(IdVal))
1832 return MatchOperand_ParseFail;
1833 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
1834 assert( MCE && "Unexpected MCExpr type.");
1835 int64_t Val = MCE->getValue();
1836 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1837 Operands.push_back(MipsOperand::CreateImm(
1838 MCConstantExpr::Create(0 - Val, getContext()), S, E));
1839 return MatchOperand_Success;
1840}
1841
Jack Carterdc1e35d2012-09-06 20:00:02 +00001842MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1843
1844 MCSymbolRefExpr::VariantKind VK
1845 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1846 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1847 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1848 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1849 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1850 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1851 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1852 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1853 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1854 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1855 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1856 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1857 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1858 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1859 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1860 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1861 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1862 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1863 .Default(MCSymbolRefExpr::VK_None);
1864
1865 return VK;
1866}
Jack Cartera63b16a2012-09-07 00:23:42 +00001867
Rafael Espindola870c4e92012-01-11 03:56:41 +00001868bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001869ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001870 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001871 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001872 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001873 Parser.eatToEndOfStatement();
1874 return Error(NameLoc, "Unknown instruction");
1875 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001876 // First operand in MCInst is instruction mnemonic.
1877 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001878
1879 // Read the remaining operands.
1880 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1881 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001882 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001883 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001884 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001885 return Error(Loc, "unexpected token in argument list");
1886 }
1887
Jack Carterd0bd6422013-04-18 00:41:53 +00001888 while (getLexer().is(AsmToken::Comma)) {
1889 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001890 // Parse and remember the operand.
1891 if (ParseOperand(Operands, Name)) {
1892 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001893 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001894 return Error(Loc, "unexpected token in argument list");
1895 }
1896 }
1897 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001898 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1899 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001900 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001901 return Error(Loc, "unexpected token in argument list");
1902 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001903 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001904 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001905}
1906
Jack Carter0b744b32012-10-04 02:29:46 +00001907bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001908 SMLoc Loc = getLexer().getLoc();
1909 Parser.eatToEndOfStatement();
1910 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001911}
1912
1913bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001914 // Line should look like: ".set noat".
1915 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001916 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001917 // eat noat
1918 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001919 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001920 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1921 reportParseError("unexpected token in statement");
1922 return false;
1923 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001924 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001925 return false;
1926}
Jack Carterd0bd6422013-04-18 00:41:53 +00001927
Jack Carter0b744b32012-10-04 02:29:46 +00001928bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001929 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001930 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001931 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001932 getParser().Lex();
1933 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001934 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001935 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001936 return false;
1937 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001938 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001939 if (getLexer().isNot(AsmToken::Dollar)) {
1940 reportParseError("unexpected token in statement");
1941 return false;
1942 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001943 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001944 const AsmToken &Reg = Parser.getTok();
1945 if (Reg.is(AsmToken::Identifier)) {
1946 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1947 } else if (Reg.is(AsmToken::Integer)) {
1948 AtRegNo = Reg.getIntVal();
1949 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001950 reportParseError("unexpected token in statement");
1951 return false;
1952 }
Jack Carter1ac53222013-02-20 23:11:17 +00001953
Jack Carterd0bd6422013-04-18 00:41:53 +00001954 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001955 reportParseError("unexpected token in statement");
1956 return false;
1957 }
1958
1959 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001960 reportParseError("unexpected token in statement");
1961 return false;
1962 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001963 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001964
1965 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1966 reportParseError("unexpected token in statement");
1967 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001968 }
1969 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001970 return false;
1971 } else {
1972 reportParseError("unexpected token in statement");
1973 return false;
1974 }
1975}
1976
1977bool MipsAsmParser::parseSetReorderDirective() {
1978 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001979 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001980 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1981 reportParseError("unexpected token in statement");
1982 return false;
1983 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001984 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001985 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001986 return false;
1987}
1988
1989bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001990 Parser.Lex();
1991 // If this is not the end of the statement, report an error.
1992 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1993 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001994 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001995 }
1996 Options.setNoreorder();
1997 Parser.Lex(); // Consume the EndOfStatement.
1998 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001999}
2000
2001bool MipsAsmParser::parseSetMacroDirective() {
2002 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002003 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002004 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2005 reportParseError("unexpected token in statement");
2006 return false;
2007 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002008 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002009 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002010 return false;
2011}
2012
2013bool MipsAsmParser::parseSetNoMacroDirective() {
2014 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002015 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002016 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2017 reportParseError("`noreorder' must be set before `nomacro'");
2018 return false;
2019 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002020 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002021 reportParseError("`noreorder' must be set before `nomacro'");
2022 return false;
2023 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002024 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002025 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002026 return false;
2027}
Jack Carterd76b2372013-03-21 21:44:16 +00002028
2029bool MipsAsmParser::parseSetAssignment() {
2030 StringRef Name;
2031 const MCExpr *Value;
2032
2033 if (Parser.parseIdentifier(Name))
2034 reportParseError("expected identifier after .set");
2035
2036 if (getLexer().isNot(AsmToken::Comma))
2037 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002038 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002039
Jack Carter02593002013-05-28 22:21:05 +00002040 if (getLexer().is(AsmToken::Dollar)) {
2041 MCSymbol *Symbol;
2042 SMLoc DollarLoc = getLexer().getLoc();
2043 // Consume the dollar sign, and check for a following identifier.
2044 Parser.Lex();
2045 // We have a '$' followed by something, make sure they are adjacent.
2046 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2047 return true;
2048 StringRef Res = StringRef(DollarLoc.getPointer(),
2049 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2050 Symbol = getContext().GetOrCreateSymbol(Res);
2051 Parser.Lex();
2052 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
2053 getContext());
2054 } else if (Parser.parseExpression(Value))
2055 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002056
Jack Carterd0bd6422013-04-18 00:41:53 +00002057 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002058 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002059 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002060 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002061 Sym = getContext().GetOrCreateSymbol(Name);
2062 Sym->setVariableValue(Value);
2063
2064 return false;
2065}
Jack Carterd0bd6422013-04-18 00:41:53 +00002066
Jack Carter0b744b32012-10-04 02:29:46 +00002067bool MipsAsmParser::parseDirectiveSet() {
2068
Jack Carterd0bd6422013-04-18 00:41:53 +00002069 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002070 const AsmToken &Tok = Parser.getTok();
2071
2072 if (Tok.getString() == "noat") {
2073 return parseSetNoAtDirective();
2074 } else if (Tok.getString() == "at") {
2075 return parseSetAtDirective();
2076 } else if (Tok.getString() == "reorder") {
2077 return parseSetReorderDirective();
2078 } else if (Tok.getString() == "noreorder") {
2079 return parseSetNoReorderDirective();
2080 } else if (Tok.getString() == "macro") {
2081 return parseSetMacroDirective();
2082 } else if (Tok.getString() == "nomacro") {
2083 return parseSetNoMacroDirective();
2084 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002085 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002086 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002087 return false;
2088 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002089 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002090 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002091 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002092 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002093 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002094 parseSetAssignment();
2095 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002096 }
Jack Carter07c818d2013-01-25 01:31:34 +00002097
Jack Carter0b744b32012-10-04 02:29:46 +00002098 return true;
2099}
2100
Jack Carter07c818d2013-01-25 01:31:34 +00002101/// parseDirectiveWord
2102/// ::= .word [ expression (, expression)* ]
2103bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2105 for (;;) {
2106 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002107 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002108 return true;
2109
2110 getParser().getStreamer().EmitValue(Value, Size);
2111
2112 if (getLexer().is(AsmToken::EndOfStatement))
2113 break;
2114
2115 // FIXME: Improve diagnostic.
2116 if (getLexer().isNot(AsmToken::Comma))
2117 return Error(L, "unexpected token in directive");
2118 Parser.Lex();
2119 }
2120 }
2121
2122 Parser.Lex();
2123 return false;
2124}
2125
Jack Carter0b744b32012-10-04 02:29:46 +00002126bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00002127
Jack Carter07c818d2013-01-25 01:31:34 +00002128 StringRef IDVal = DirectiveID.getString();
2129
Jack Carterd0bd6422013-04-18 00:41:53 +00002130 if (IDVal == ".ent") {
2131 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002132 Parser.Lex();
2133 return false;
2134 }
2135
Jack Carter07c818d2013-01-25 01:31:34 +00002136 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002137 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002138 Parser.Lex();
2139 return false;
2140 }
2141
Jack Carter07c818d2013-01-25 01:31:34 +00002142 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002143 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002144 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002145 return false;
2146 }
2147
Jack Carter07c818d2013-01-25 01:31:34 +00002148 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002149 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002150 }
2151
Jack Carter07c818d2013-01-25 01:31:34 +00002152 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002153 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002154 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002155 return false;
2156 }
2157
Jack Carter07c818d2013-01-25 01:31:34 +00002158 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002159 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002160 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002161 return false;
2162 }
2163
Jack Carter07c818d2013-01-25 01:31:34 +00002164 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002165 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002166 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002167 return false;
2168 }
2169
Jack Carter07c818d2013-01-25 01:31:34 +00002170 if (IDVal == ".word") {
2171 parseDirectiveWord(4, DirectiveID.getLoc());
2172 return false;
2173 }
2174
Rafael Espindola870c4e92012-01-11 03:56:41 +00002175 return true;
2176}
2177
Rafael Espindola870c4e92012-01-11 03:56:41 +00002178extern "C" void LLVMInitializeMipsAsmParser() {
2179 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2180 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2181 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2182 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2183}
Jack Carterb4dbc172012-09-05 23:34:03 +00002184
2185#define GET_REGISTER_MATCHER
2186#define GET_MATCHER_IMPLEMENTATION
2187#include "MipsGenAsmMatcher.inc"