blob: 16260857c247a1f59bf9644262d60e7588a63a4f [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"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000012#include "MipsTargetStreamer.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000013#include "llvm/ADT/StringSwitch.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/MC/MCParser/MCAsmLexer.h"
18#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000019#include "llvm/MC/MCStreamer.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000022#include "llvm/MC/MCTargetAsmParser.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000023#include "llvm/Support/TargetRegistry.h"
Jack Carter02593002013-05-28 22:21:05 +000024#include "llvm/ADT/APInt.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000025
26using namespace llvm;
27
Joey Gouly0e76fa72013-09-12 10:28:05 +000028namespace llvm {
29class MCInstrInfo;
30}
31
Rafael Espindola870c4e92012-01-11 03:56:41 +000032namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000033class MipsAssemblerOptions {
34public:
35 MipsAssemblerOptions():
36 aTReg(1), reorder(true), macro(true) {
37 }
Jack Carterb4dbc172012-09-05 23:34:03 +000038
Jack Carter0b744b32012-10-04 02:29:46 +000039 unsigned getATRegNum() {return aTReg;}
40 bool setATReg(unsigned Reg);
41
42 bool isReorder() {return reorder;}
43 void setReorder() {reorder = true;}
44 void setNoreorder() {reorder = false;}
45
46 bool isMacro() {return macro;}
47 void setMacro() {macro = true;}
48 void setNomacro() {macro = false;}
49
50private:
51 unsigned aTReg;
52 bool reorder;
53 bool macro;
54};
55}
56
57namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000058class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000059
Rafael Espindolaa17151a2013-10-08 13:08:17 +000060 MipsTargetStreamer &getTargetStreamer() {
61 MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer();
62 return static_cast<MipsTargetStreamer &>(TS);
63 }
64
Jack Carterb4dbc172012-09-05 23:34:03 +000065 MCSubtargetInfo &STI;
66 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000067 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000068 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000069
Akira Hatanaka7605630c2012-08-17 20:16:42 +000070#define GET_ASSEMBLER_HEADER
71#include "MipsGenAsmMatcher.inc"
72
Chad Rosier49963552012-10-13 00:26:04 +000073 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +000074 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000075 MCStreamer &Out, unsigned &ErrorInfo,
76 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000077
78 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
79
Chad Rosierf0e87202012-10-25 20:41:34 +000080 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
81 SMLoc NameLoc,
Akira Hatanaka7605630c2012-08-17 20:16:42 +000082 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000083
84 bool ParseDirective(AsmToken DirectiveID);
85
Jack Carterb4dbc172012-09-05 23:34:03 +000086 MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +000087 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
88 int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000089
90 MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +000091 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
92 int RegKind);
93
94 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000095 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
96
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000097 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
98
99 MipsAsmParser::OperandMatchResultTy
100 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
101
Jack Carter873c7242013-01-12 01:03:14 +0000102 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000103 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000104
105 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000106 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000107
108 MipsAsmParser::OperandMatchResultTy
109 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
110
111 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +0000112 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000113
Vladimir Medic233dd512013-06-24 10:05:34 +0000114 MipsAsmParser::OperandMatchResultTy
115 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
116
117 MipsAsmParser::OperandMatchResultTy
118 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
119
120 MipsAsmParser::OperandMatchResultTy
121 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
122
Vladimir Medic643b3982013-07-30 10:12:14 +0000123 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000124 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
125
126 MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +0000127 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
128
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000129 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000130 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000131
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000132 MipsAsmParser::OperandMatchResultTy
133 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
134
135 MipsAsmParser::OperandMatchResultTy
136 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
137
Vladimir Medic05bcde62013-09-16 10:29:42 +0000138 MipsAsmParser::OperandMatchResultTy
139 parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
140
Jack Carter5dc8ac92013-09-25 23:50:44 +0000141 MipsAsmParser::OperandMatchResultTy
142 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
143
144 MipsAsmParser::OperandMatchResultTy
145 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
146
147 MipsAsmParser::OperandMatchResultTy
148 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
149
150 MipsAsmParser::OperandMatchResultTy
151 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
152
Vladimir Medic2b953d02013-10-01 09:48:56 +0000153 MipsAsmParser::OperandMatchResultTy
154 parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
155
Jack Carterd76b2372013-03-21 21:44:16 +0000156 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000157 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000158
Jack Carterb4dbc172012-09-05 23:34:03 +0000159 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
160 StringRef Mnemonic);
161
Jack Carter873c7242013-01-12 01:03:14 +0000162 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000163
164 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000165 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000166
Jack Carter30a59822012-10-04 04:03:53 +0000167 bool needsExpansion(MCInst &Inst);
168
169 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000170 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000171 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000172 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000173 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
174 SmallVectorImpl<MCInst> &Instructions);
175 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
176 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000177 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions,
179 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000180 bool reportParseError(StringRef ErrorMsg);
181
Jack Carterb5cf5902013-04-17 00:18:04 +0000182 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000183 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000184
Jack Carterb5cf5902013-04-17 00:18:04 +0000185 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
186
187 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000188 bool parseDirectiveSet();
Rafael Espindolaac4ad252013-10-05 16:42:21 +0000189 bool parseDirectiveMipsHackStocg();
190 bool parseDirectiveMipsHackELFFlags();
Jack Carter0b744b32012-10-04 02:29:46 +0000191
192 bool parseSetAtDirective();
193 bool parseSetNoAtDirective();
194 bool parseSetMacroDirective();
195 bool parseSetNoMacroDirective();
196 bool parseSetReorderDirective();
197 bool parseSetNoReorderDirective();
198
Jack Carterd76b2372013-03-21 21:44:16 +0000199 bool parseSetAssignment();
200
Jack Carter07c818d2013-01-25 01:31:34 +0000201 bool parseDirectiveWord(unsigned Size, SMLoc L);
202
Jack Carterdc1e35d2012-09-06 20:00:02 +0000203 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000204
Jack Carterb4dbc172012-09-05 23:34:03 +0000205 bool isMips64() const {
206 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
207 }
208
Jack Cartera63b16a2012-09-07 00:23:42 +0000209 bool isFP64() const {
210 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
211 }
212
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000213 bool isN64() const {
214 return STI.getFeatureBits() & Mips::FeatureN64;
215 }
216
Jack Carter873c7242013-01-12 01:03:14 +0000217 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000218
Jack Carter1ac53222013-02-20 23:11:17 +0000219 int matchCPURegisterName(StringRef Symbol);
220
Jack Carter873c7242013-01-12 01:03:14 +0000221 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000222
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000223 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000224
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000225 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000226
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000227 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000228
Jack Carter5dc8ac92013-09-25 23:50:44 +0000229 int matchMSA128RegisterName(StringRef Name);
230
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000231 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000232
Jack Carterd0bd6422013-04-18 00:41:53 +0000233 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000234
Jack Carter1ac53222013-02-20 23:11:17 +0000235 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000236
237 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
238 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000239
240 // Helper function that checks if the value of a vector index is within the
241 // boundaries of accepted values for each RegisterKind
242 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
243 bool validateMSAIndex(int Val, int RegKind);
244
Rafael Espindola870c4e92012-01-11 03:56:41 +0000245public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000246 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
247 const MCInstrInfo &MII)
248 : MCTargetAsmParser(), STI(sti), Parser(parser),
249 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000250 // Initialize the set of available features.
251 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000252 }
253
Jack Carterb4dbc172012-09-05 23:34:03 +0000254 MCAsmParser &getParser() const { return Parser; }
255 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
256
Rafael Espindola870c4e92012-01-11 03:56:41 +0000257};
258}
259
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000260namespace {
261
262/// MipsOperand - Instances of this class represent a parsed Mips machine
263/// instruction.
264class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000265
Jack Carter873c7242013-01-12 01:03:14 +0000266public:
267 enum RegisterKind {
268 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000269 Kind_GPR32,
270 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000271 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000272 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000273 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000274 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000275 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000276 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000277 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000278 Kind_ACC64DSP,
279 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000280 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000281 Kind_COP2,
282 Kind_MSA128BRegs,
283 Kind_MSA128HRegs,
284 Kind_MSA128WRegs,
285 Kind_MSA128DRegs
Jack Carter873c7242013-01-12 01:03:14 +0000286 };
287
288private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000289 enum KindTy {
290 k_CondCode,
291 k_CoprocNum,
292 k_Immediate,
293 k_Memory,
294 k_PostIndexRegister,
295 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000296 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000297 k_Token
298 } Kind;
299
300 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000301
Eric Christopher8996c5d2013-03-15 00:42:55 +0000302 struct Token {
303 const char *Data;
304 unsigned Length;
305 };
306
307 struct RegOp {
308 unsigned RegNum;
309 RegisterKind Kind;
310 };
311
312 struct ImmOp {
313 const MCExpr *Val;
314 };
315
316 struct MemOp {
317 unsigned Base;
318 const MCExpr *Off;
319 };
320
Jack Carterb4dbc172012-09-05 23:34:03 +0000321 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000322 struct Token Tok;
323 struct RegOp Reg;
324 struct ImmOp Imm;
325 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000326 };
327
328 SMLoc StartLoc, EndLoc;
329
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000330public:
331 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000332 assert(N == 1 && "Invalid number of operands!");
333 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000334 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000335
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000336 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
337 assert(N == 1 && "Invalid number of operands!");
338 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
339 }
340
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000341 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000342 // Add as immediate when possible. Null MCExpr = 0.
343 if (Expr == 0)
344 Inst.addOperand(MCOperand::CreateImm(0));
345 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
346 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
347 else
348 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000349 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000350
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000351 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000352 assert(N == 1 && "Invalid number of operands!");
353 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000354 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000355 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000356
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000357 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000358 assert(N == 2 && "Invalid number of operands!");
359
360 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
361
362 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000363 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000364 }
365
366 bool isReg() const { return Kind == k_Register; }
367 bool isImm() const { return Kind == k_Immediate; }
368 bool isToken() const { return Kind == k_Token; }
369 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000370 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000371 bool isInvNum() const { return Kind == k_Immediate; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000372
373 StringRef getToken() const {
374 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000375 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000376 }
377
378 unsigned getReg() const {
379 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000380 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000381 }
382
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000383 unsigned getPtrReg() const {
384 assert((Kind == k_PtrReg) && "Invalid access!");
385 return Reg.RegNum;
386 }
387
Jack Carter873c7242013-01-12 01:03:14 +0000388 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000389 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000390 Reg.Kind = RegKind;
391 }
392
Jack Carterb4dbc172012-09-05 23:34:03 +0000393 const MCExpr *getImm() const {
394 assert((Kind == k_Immediate) && "Invalid access!");
395 return Imm.Val;
396 }
397
Jack Carterdc1e35d2012-09-06 20:00:02 +0000398 unsigned getMemBase() const {
399 assert((Kind == k_Memory) && "Invalid access!");
400 return Mem.Base;
401 }
402
403 const MCExpr *getMemOff() const {
404 assert((Kind == k_Memory) && "Invalid access!");
405 return Mem.Off;
406 }
407
Jack Carterb4dbc172012-09-05 23:34:03 +0000408 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
409 MipsOperand *Op = new MipsOperand(k_Token);
410 Op->Tok.Data = Str.data();
411 Op->Tok.Length = Str.size();
412 Op->StartLoc = S;
413 Op->EndLoc = S;
414 return Op;
415 }
416
417 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
418 MipsOperand *Op = new MipsOperand(k_Register);
419 Op->Reg.RegNum = RegNum;
420 Op->StartLoc = S;
421 Op->EndLoc = E;
422 return Op;
423 }
424
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000425 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
426 MipsOperand *Op = new MipsOperand(k_PtrReg);
427 Op->Reg.RegNum = RegNum;
428 Op->StartLoc = S;
429 Op->EndLoc = E;
430 return Op;
431 }
432
Jack Carterb4dbc172012-09-05 23:34:03 +0000433 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
434 MipsOperand *Op = new MipsOperand(k_Immediate);
435 Op->Imm.Val = Val;
436 Op->StartLoc = S;
437 Op->EndLoc = E;
438 return Op;
439 }
440
Jack Carterdc1e35d2012-09-06 20:00:02 +0000441 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
442 SMLoc S, SMLoc E) {
443 MipsOperand *Op = new MipsOperand(k_Memory);
444 Op->Mem.Base = Base;
445 Op->Mem.Off = Off;
446 Op->StartLoc = S;
447 Op->EndLoc = E;
448 return Op;
449 }
450
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000451 bool isGPR32Asm() const {
452 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000453 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000454 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000455 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
456 }
457
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000458 bool isGPR64Asm() const {
459 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000460 }
Jack Carter873c7242013-01-12 01:03:14 +0000461
462 bool isHWRegsAsm() const {
463 assert((Kind == k_Register) && "Invalid access!");
464 return Reg.Kind == Kind_HWRegs;
465 }
Jack Carter873c7242013-01-12 01:03:14 +0000466
Jack Carter873c7242013-01-12 01:03:14 +0000467 bool isCCRAsm() const {
468 assert((Kind == k_Register) && "Invalid access!");
469 return Reg.Kind == Kind_CCRRegs;
470 }
471
Vladimir Medic233dd512013-06-24 10:05:34 +0000472 bool isAFGR64Asm() const {
473 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
474 }
475
476 bool isFGR64Asm() const {
477 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
478 }
479
480 bool isFGR32Asm() const {
481 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
482 }
483
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000484 bool isFGRH32Asm() const {
485 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
486 }
487
Vladimir Medic643b3982013-07-30 10:12:14 +0000488 bool isFCCRegsAsm() const {
489 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
490 }
491
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000492 bool isACC64DSPAsm() const {
493 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000494 }
495
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000496 bool isLO32DSPAsm() const {
497 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
498 }
499
500 bool isHI32DSPAsm() const {
501 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
502 }
503
Vladimir Medic05bcde62013-09-16 10:29:42 +0000504 bool isCOP2Asm() const {
505 return Kind == k_Register && Reg.Kind == Kind_COP2;
506 }
507
Jack Carter5dc8ac92013-09-25 23:50:44 +0000508 bool isMSA128BAsm() const {
509 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
510 }
511
512 bool isMSA128HAsm() const {
513 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
514 }
515
516 bool isMSA128WAsm() const {
517 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
518 }
519
520 bool isMSA128DAsm() const {
521 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
522 }
523
Jack Carterb4dbc172012-09-05 23:34:03 +0000524 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000525 SMLoc getStartLoc() const {
526 return StartLoc;
527 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000528 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000529 SMLoc getEndLoc() const {
530 return EndLoc;
531 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000532
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000533 virtual void print(raw_ostream &OS) const {
534 llvm_unreachable("unimplemented!");
535 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000536}; // class MipsOperand
537} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000538
Jack Carter9e65aa32013-03-22 00:05:30 +0000539namespace llvm {
540extern const MCInstrDesc MipsInsts[];
541}
542static const MCInstrDesc &getInstDesc(unsigned Opcode) {
543 return MipsInsts[Opcode];
544}
545
546bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000547 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000548 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
549 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000550 if (MCID.hasDelaySlot() && Options.isReorder()) {
551 // If this instruction has a delay slot and .set reorder is active,
552 // emit a NOP after it.
553 Instructions.push_back(Inst);
554 MCInst NopInst;
555 NopInst.setOpcode(Mips::SLL);
556 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
557 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
558 NopInst.addOperand(MCOperand::CreateImm(0));
559 Instructions.push_back(NopInst);
560 return false;
561 }
562
Jack Carter9e65aa32013-03-22 00:05:30 +0000563 if (MCID.mayLoad() || MCID.mayStore()) {
564 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000565 // reference or immediate we may have to expand instructions.
566 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000567 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000568 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
569 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000570 MCOperand &Op = Inst.getOperand(i);
571 if (Op.isImm()) {
572 int MemOffset = Op.getImm();
573 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000574 // Offset can't exceed 16bit value.
575 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000576 return false;
577 }
578 } else if (Op.isExpr()) {
579 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000580 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000581 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000582 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000583 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000584 // Expand symbol.
585 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000586 return false;
587 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000588 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000589 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000590 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000591 }
592 }
593 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000594 } // for
595 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000596
597 if (needsExpansion(Inst))
598 expandInstruction(Inst, IDLoc, Instructions);
599 else
600 Instructions.push_back(Inst);
601
602 return false;
603}
604
Jack Carter30a59822012-10-04 04:03:53 +0000605bool MipsAsmParser::needsExpansion(MCInst &Inst) {
606
Jack Carterd0bd6422013-04-18 00:41:53 +0000607 switch (Inst.getOpcode()) {
608 case Mips::LoadImm32Reg:
609 case Mips::LoadAddr32Imm:
610 case Mips::LoadAddr32Reg:
611 return true;
612 default:
613 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000614 }
615}
Jack Carter92995f12012-10-06 00:53:28 +0000616
Jack Carter30a59822012-10-04 04:03:53 +0000617void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000618 SmallVectorImpl<MCInst> &Instructions) {
619 switch (Inst.getOpcode()) {
620 case Mips::LoadImm32Reg:
621 return expandLoadImm(Inst, IDLoc, Instructions);
622 case Mips::LoadAddr32Imm:
623 return expandLoadAddressImm(Inst, IDLoc, Instructions);
624 case Mips::LoadAddr32Reg:
625 return expandLoadAddressReg(Inst, IDLoc, Instructions);
626 }
Jack Carter30a59822012-10-04 04:03:53 +0000627}
Jack Carter92995f12012-10-06 00:53:28 +0000628
Jack Carter30a59822012-10-04 04:03:53 +0000629void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000630 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000631 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000632 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000633 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000634 const MCOperand &RegOp = Inst.getOperand(0);
635 assert(RegOp.isReg() && "expected register operand kind");
636
637 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000638 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000639 if (0 <= ImmValue && ImmValue <= 65535) {
640 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000641 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000642 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000643 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000644 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000645 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000646 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000647 } else if (ImmValue < 0 && ImmValue >= -32768) {
648 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000649 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000650 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000651 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000652 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000653 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000654 Instructions.push_back(tmpInst);
655 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000656 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000657 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000658 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000659 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000660 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
661 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000662 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000663 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000664 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000665 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
666 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
667 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
668 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000669 Instructions.push_back(tmpInst);
670 }
671}
Jack Carter92995f12012-10-06 00:53:28 +0000672
Jack Carter543fdf82012-10-09 23:29:45 +0000673void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000674 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000675 MCInst tmpInst;
676 const MCOperand &ImmOp = Inst.getOperand(2);
677 assert(ImmOp.isImm() && "expected immediate operand kind");
678 const MCOperand &SrcRegOp = Inst.getOperand(1);
679 assert(SrcRegOp.isReg() && "expected register operand kind");
680 const MCOperand &DstRegOp = Inst.getOperand(0);
681 assert(DstRegOp.isReg() && "expected register operand kind");
682 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000683 if (-32768 <= ImmValue && ImmValue <= 65535) {
684 // For -32768 <= j <= 65535.
685 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000686 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000687 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
688 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
689 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
690 Instructions.push_back(tmpInst);
691 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000692 // For any other value of j that is representable as a 32-bit integer.
693 // la d,j(s) => lui d,hi16(j)
694 // ori d,d,lo16(j)
695 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000696 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000697 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
698 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
699 Instructions.push_back(tmpInst);
700 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000701 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000702 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
703 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
704 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
705 Instructions.push_back(tmpInst);
706 tmpInst.clear();
707 tmpInst.setOpcode(Mips::ADDu);
708 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
709 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
710 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
711 Instructions.push_back(tmpInst);
712 }
713}
714
715void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000716 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000717 MCInst tmpInst;
718 const MCOperand &ImmOp = Inst.getOperand(1);
719 assert(ImmOp.isImm() && "expected immediate operand kind");
720 const MCOperand &RegOp = Inst.getOperand(0);
721 assert(RegOp.isReg() && "expected register operand kind");
722 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000723 if (-32768 <= ImmValue && ImmValue <= 65535) {
724 // For -32768 <= j <= 65535.
725 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000726 tmpInst.setOpcode(Mips::ADDiu);
727 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000728 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000729 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
730 Instructions.push_back(tmpInst);
731 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000732 // For any other value of j that is representable as a 32-bit integer.
733 // la d,j => lui d,hi16(j)
734 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000735 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000736 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
737 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
738 Instructions.push_back(tmpInst);
739 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000740 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000741 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
742 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
743 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
744 Instructions.push_back(tmpInst);
745 }
746}
747
Jack Carter9e65aa32013-03-22 00:05:30 +0000748void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000749 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000750 const MCSymbolRefExpr *SR;
751 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000752 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000753 const MCExpr *ExprOffset;
754 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000755 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
756 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000757 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000758 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
759 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000760 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000761 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
762 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000763 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000764 if (isImmOpnd) {
765 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
766 ImmOffset = Inst.getOperand(2).getImm();
767 LoOffset = ImmOffset & 0x0000ffff;
768 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000769 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000770 if (LoOffset & 0x8000)
771 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000772 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000773 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000774 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000775 TempInst.setLoc(IDLoc);
776 // 1st instruction in expansion is LUi. For load instruction we can use
777 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000778 // but for stores we must use $at.
779 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000780 TempInst.setOpcode(Mips::LUi);
781 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
782 if (isImmOpnd)
783 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
784 else {
785 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
786 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000787 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
788 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
789 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000790 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000791 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000792 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000793 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000794 }
795 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000796 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000797 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000798 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000799 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000800 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000801 TempInst.setOpcode(Mips::ADDu);
802 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
803 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
804 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
805 Instructions.push_back(TempInst);
806 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000807 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000808 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000809 TempInst.setOpcode(Inst.getOpcode());
810 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
811 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
812 if (isImmOpnd)
813 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
814 else {
815 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000816 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
817 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
818 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000819 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000820 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000821 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000822 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000823 }
824 }
825 Instructions.push_back(TempInst);
826 TempInst.clear();
827}
828
Rafael Espindola870c4e92012-01-11 03:56:41 +0000829bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000830MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000831 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000832 MCStreamer &Out, unsigned &ErrorInfo,
833 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000834 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000835 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000836 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000837 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000838
839 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000840 default:
841 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000842 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000843 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000844 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000845 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000846 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000847 return false;
848 }
849 case Match_MissingFeature:
850 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
851 return true;
852 case Match_InvalidOperand: {
853 SMLoc ErrorLoc = IDLoc;
854 if (ErrorInfo != ~0U) {
855 if (ErrorInfo >= Operands.size())
856 return Error(IDLoc, "too few operands for instruction");
857
Jack Carterd0bd6422013-04-18 00:41:53 +0000858 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
859 if (ErrorLoc == SMLoc())
860 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000861 }
862
863 return Error(ErrorLoc, "invalid operand for instruction");
864 }
865 case Match_MnemonicFail:
866 return Error(IDLoc, "invalid instruction");
867 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000868 return true;
869}
870
Jack Carter1ac53222013-02-20 23:11:17 +0000871int MipsAsmParser::matchCPURegisterName(StringRef Name) {
872 int CC;
873
874 if (Name == "at")
875 return getATReg();
876
877 CC = StringSwitch<unsigned>(Name)
878 .Case("zero", 0)
879 .Case("a0", 4)
880 .Case("a1", 5)
881 .Case("a2", 6)
882 .Case("a3", 7)
883 .Case("v0", 2)
884 .Case("v1", 3)
885 .Case("s0", 16)
886 .Case("s1", 17)
887 .Case("s2", 18)
888 .Case("s3", 19)
889 .Case("s4", 20)
890 .Case("s5", 21)
891 .Case("s6", 22)
892 .Case("s7", 23)
893 .Case("k0", 26)
894 .Case("k1", 27)
895 .Case("sp", 29)
896 .Case("fp", 30)
897 .Case("gp", 28)
898 .Case("ra", 31)
899 .Case("t0", 8)
900 .Case("t1", 9)
901 .Case("t2", 10)
902 .Case("t3", 11)
903 .Case("t4", 12)
904 .Case("t5", 13)
905 .Case("t6", 14)
906 .Case("t7", 15)
907 .Case("t8", 24)
908 .Case("t9", 25)
909 .Default(-1);
910
Jack Carterd0bd6422013-04-18 00:41:53 +0000911 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000912 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
913 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000914 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000915 CC += 4;
916
917 if (CC == -1 && isMips64())
918 CC = StringSwitch<unsigned>(Name)
919 .Case("a4", 8)
920 .Case("a5", 9)
921 .Case("a6", 10)
922 .Case("a7", 11)
923 .Case("kt0", 26)
924 .Case("kt1", 27)
925 .Case("s8", 30)
926 .Default(-1);
927
928 return CC;
929}
Jack Carterd0bd6422013-04-18 00:41:53 +0000930
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000931int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000932
Jack Cartera63b16a2012-09-07 00:23:42 +0000933 if (Name[0] == 'f') {
934 StringRef NumString = Name.substr(1);
935 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000936 if (NumString.getAsInteger(10, IntVal))
937 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000938 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000939 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000940 return IntVal;
941 }
942 return -1;
943}
Jack Cartera63b16a2012-09-07 00:23:42 +0000944
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000945int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
946
947 if (Name.startswith("fcc")) {
948 StringRef NumString = Name.substr(3);
949 unsigned IntVal;
950 if (NumString.getAsInteger(10, IntVal))
951 return -1; // This is not an integer.
952 if (IntVal > 7) // There are only 8 fcc registers.
953 return -1;
954 return IntVal;
955 }
956 return -1;
957}
958
959int MipsAsmParser::matchACRegisterName(StringRef Name) {
960
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000961 if (Name.startswith("ac")) {
962 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000963 unsigned IntVal;
964 if (NumString.getAsInteger(10, IntVal))
965 return -1; // This is not an integer.
966 if (IntVal > 3) // There are only 3 acc registers.
967 return -1;
968 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000969 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000970 return -1;
971}
Jack Carterd0bd6422013-04-18 00:41:53 +0000972
Jack Carter5dc8ac92013-09-25 23:50:44 +0000973int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
974 unsigned IntVal;
975
976 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
977 return -1;
978
979 if (IntVal > 31)
980 return -1;
981
982 return IntVal;
983}
984
Vladimir Medic8cd17102013-06-20 11:21:49 +0000985int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
986
Vladimir Medic8cd17102013-06-20 11:21:49 +0000987 int CC;
988 CC = matchCPURegisterName(Name);
989 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000990 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
991 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000992 CC = matchFPURegisterName(Name);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000993 //TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +0000994 if (CC != -1)
995 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
996 : Mips::FGR32RegClassID);
997 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000998}
999
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001000int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001001
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001002 switch (RegKind) {
1003 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
1004 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
1005 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
1006 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001007 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001008 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
1009 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
1010 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
1011 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
1012 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
Jack Carter5dc8ac92013-09-25 23:50:44 +00001013 case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
1014 case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
1015 case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
1016 case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001017 default :return -1;
1018 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001019
Jack Cartera63b16a2012-09-07 00:23:42 +00001020}
Jack Carterb4dbc172012-09-05 23:34:03 +00001021
Jack Carter0b744b32012-10-04 02:29:46 +00001022bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1023 if (Reg > 31)
1024 return false;
1025
1026 aTReg = Reg;
1027 return true;
1028}
1029
Jack Carter1ac53222013-02-20 23:11:17 +00001030int MipsAsmParser::getATReg() {
1031 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +00001032}
1033
Jack Carterd0bd6422013-04-18 00:41:53 +00001034unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001035 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001036}
1037
Jack Carter873c7242013-01-12 01:03:14 +00001038int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001039 if (RegNum >
1040 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001041 return -1;
1042
Jack Carter873c7242013-01-12 01:03:14 +00001043 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001044}
1045
Jack Carter873c7242013-01-12 01:03:14 +00001046int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001047 const AsmToken &Tok = Parser.getTok();
1048 int RegNum = -1;
1049
1050 if (Tok.is(AsmToken::Identifier)) {
1051 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001052 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001053 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001054 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001055 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001056 return RegNum;
1057}
1058
Jack Carterd0bd6422013-04-18 00:41:53 +00001059bool MipsAsmParser::tryParseRegisterOperand(
1060 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001061
1062 SMLoc S = Parser.getTok().getLoc();
1063 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001064
Jack Carter873c7242013-01-12 01:03:14 +00001065 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001066 if (RegNo == -1)
1067 return true;
1068
Jack Carter873c7242013-01-12 01:03:14 +00001069 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +00001070 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001071 Parser.Lex(); // Eat register token.
1072 return false;
1073}
1074
1075bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1076 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001077 // Check if the current operand has a custom associated parser, if so, try to
1078 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001079 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1080 if (ResTy == MatchOperand_Success)
1081 return false;
1082 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1083 // there was a match, but an error occurred, in which case, just return that
1084 // the operand parsing failed.
1085 if (ResTy == MatchOperand_ParseFail)
1086 return true;
1087
1088 switch (getLexer().getKind()) {
1089 default:
1090 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1091 return true;
1092 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001093 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001094 SMLoc S = Parser.getTok().getLoc();
1095 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001096 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001097 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001098 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001099 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001100 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001101 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001102 if (getLexer().isNot(AsmToken::Dollar))
1103 return true;
1104
Jack Carterd0bd6422013-04-18 00:41:53 +00001105 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001106 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001107 return true;
1108
1109 if (!getLexer().is(AsmToken::RParen))
1110 return true;
1111
1112 S = Parser.getTok().getLoc();
1113 Operands.push_back(MipsOperand::CreateToken(")", S));
1114 Parser.Lex();
1115 }
1116 return false;
1117 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001118 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001119 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001120 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001121 return true;
1122
Jack Carter873c7242013-01-12 01:03:14 +00001123 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001124
Benjamin Kramerfa530572012-09-07 09:47:42 +00001125 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001126
Jack Carterd0bd6422013-04-18 00:41:53 +00001127 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001128 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001129 getContext());
1130
1131 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1132 return false;
1133 }
1134 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001135 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001136 // we need to assigne the propper RegisterKind.
1137 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1138 return false;
1139 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001140 case AsmToken::LParen:
1141 case AsmToken::Minus:
1142 case AsmToken::Plus:
1143 case AsmToken::Integer:
1144 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001145 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001146 const MCExpr *IdVal;
1147 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001148 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001149 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001150 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001151 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1152 return false;
1153 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001154 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001155 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001156 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001157 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001158 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001159 return true;
1160
Jack Carter873c7242013-01-12 01:03:14 +00001161 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1162
Jack Carterdc1e35d2012-09-06 20:00:02 +00001163 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1164 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001165 } // case AsmToken::Percent
1166 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001167 return true;
1168}
1169
Jack Carterb5cf5902013-04-17 00:18:04 +00001170const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1171 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001172 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001173 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001174 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001175 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001176 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001177 short Val = MCE->getValue();
1178 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001179 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001180 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001181 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001182 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001183 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001184 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001185 if (LoSign)
1186 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001187 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001188 } else {
1189 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001190 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001191 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001192 }
1193
Jack Carterb5cf5902013-04-17 00:18:04 +00001194 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001195 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001196 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001197 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001198 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001199 return Res;
1200 }
1201
1202 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001203 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1204 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001205 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1206 return Res;
1207 }
1208
1209 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001210 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1211 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1212 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001213 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001214 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001215 return Expr;
1216}
1217
1218bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1219
1220 switch (Expr->getKind()) {
1221 case MCExpr::Constant:
1222 return true;
1223 case MCExpr::SymbolRef:
1224 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1225 case MCExpr::Binary:
1226 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1227 if (!isEvaluated(BE->getLHS()))
1228 return false;
1229 return isEvaluated(BE->getRHS());
1230 }
1231 case MCExpr::Unary:
1232 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1233 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001234 return false;
1235 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001236 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001237}
Jack Carterd0bd6422013-04-18 00:41:53 +00001238
Jack Carterb5cf5902013-04-17 00:18:04 +00001239bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001240 Parser.Lex(); // Eat the % token.
1241 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001242 if (Tok.isNot(AsmToken::Identifier))
1243 return true;
1244
1245 std::string Str = Tok.getIdentifier().str();
1246
Jack Carterd0bd6422013-04-18 00:41:53 +00001247 Parser.Lex(); // Eat the identifier.
1248 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001249 const MCExpr *IdVal;
1250 SMLoc EndLoc;
1251
1252 if (getLexer().getKind() == AsmToken::LParen) {
1253 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001254 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001255 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001256 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001257 const AsmToken &nextTok = Parser.getTok();
1258 if (nextTok.isNot(AsmToken::Identifier))
1259 return true;
1260 Str += "(%";
1261 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001262 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001263 if (getLexer().getKind() != AsmToken::LParen)
1264 return true;
1265 } else
1266 break;
1267 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001268 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001269 return true;
1270
1271 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001272 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001273
1274 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001275 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001276
Jack Carterd0bd6422013-04-18 00:41:53 +00001277 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001278 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001279}
1280
Jack Carterb4dbc172012-09-05 23:34:03 +00001281bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1282 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001283 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001284 RegNo = tryParseRegister(isMips64());
1285 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001286 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001287}
1288
Jack Carterb5cf5902013-04-17 00:18:04 +00001289bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001290 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001291 bool Result = true;
1292
1293 while (getLexer().getKind() == AsmToken::LParen)
1294 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001295
Jack Carterd0bd6422013-04-18 00:41:53 +00001296 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001297 default:
1298 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001299 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001300 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001301 case AsmToken::Integer:
1302 case AsmToken::Minus:
1303 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001304 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001305 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001306 else
1307 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001308 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001309 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001310 break;
Jack Carter873c7242013-01-12 01:03:14 +00001311 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001312 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001313 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001314 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001315}
1316
Jack Carterb4dbc172012-09-05 23:34:03 +00001317MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001318 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001319
1320 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001321 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001322 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001323 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001324 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001325 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001326
Jack Carterb5cf5902013-04-17 00:18:04 +00001327 if (getLexer().getKind() == AsmToken::LParen) {
1328 Parser.Lex();
1329 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001330 }
1331
Jack Carterb5cf5902013-04-17 00:18:04 +00001332 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001333 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001334 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001335
Jack Carterd0bd6422013-04-18 00:41:53 +00001336 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001337 if (Tok.isNot(AsmToken::LParen)) {
1338 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1339 if (Mnemonic->getToken() == "la") {
1340 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001341 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001342 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1343 return MatchOperand_Success;
1344 }
1345 if (Tok.is(AsmToken::EndOfStatement)) {
1346 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001347 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001348
Jack Carterd0bd6422013-04-18 00:41:53 +00001349 // Zero register assumed, add a memory operand with ZERO as its base.
1350 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1351 : Mips::ZERO,
1352 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001353 return MatchOperand_Success;
1354 }
1355 Error(Parser.getTok().getLoc(), "'(' expected");
1356 return MatchOperand_ParseFail;
1357 }
1358
Jack Carterd0bd6422013-04-18 00:41:53 +00001359 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001360 }
1361
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001362 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1363 (int) MipsOperand::Kind_GPR32);
1364 if (Res != MatchOperand_Success)
1365 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001366
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001367 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001368 Error(Parser.getTok().getLoc(), "')' expected");
1369 return MatchOperand_ParseFail;
1370 }
1371
Jack Carter873c7242013-01-12 01:03:14 +00001372 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1373
Jack Carterd0bd6422013-04-18 00:41:53 +00001374 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001375
1376 if (IdVal == 0)
1377 IdVal = MCConstantExpr::Create(0, getContext());
1378
Jack Carterd0bd6422013-04-18 00:41:53 +00001379 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001380 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1381 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001382 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001383 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001384 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001385 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1386 int64_t Imm;
1387 if (IdVal->EvaluateAsAbsolute(Imm))
1388 IdVal = MCConstantExpr::Create(Imm, getContext());
1389 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1390 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1391 getContext());
1392 }
1393
Jack Carterdc1e35d2012-09-06 20:00:02 +00001394 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1395 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001396 return MatchOperand_Success;
1397}
1398
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001399bool
1400MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1401 int RegKind) {
1402 // If the first token is not '$' we have an error.
1403 if (Parser.getTok().isNot(AsmToken::Dollar))
1404 return false;
1405
1406 SMLoc S = Parser.getTok().getLoc();
1407 Parser.Lex();
1408 AsmToken::TokenKind TkKind = getLexer().getKind();
1409 int Reg;
1410
1411 if (TkKind == AsmToken::Integer) {
1412 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1413 regKindToRegClass(RegKind));
1414 if (Reg == -1)
1415 return false;
1416 } else if (TkKind == AsmToken::Identifier) {
1417 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1418 return false;
1419 Reg = getReg(regKindToRegClass(RegKind), Reg);
1420 } else {
1421 return false;
1422 }
1423
1424 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1425 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1426 Operands.push_back(Op);
1427 Parser.Lex();
1428 return true;
1429}
1430
1431MipsAsmParser::OperandMatchResultTy
1432MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1433 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1434 MipsOperand::Kind_GPR32;
1435
1436 // Parse index register.
1437 if (!parsePtrReg(Operands, RegKind))
1438 return MatchOperand_NoMatch;
1439
1440 // Parse '('.
1441 if (Parser.getTok().isNot(AsmToken::LParen))
1442 return MatchOperand_NoMatch;
1443
1444 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1445 Parser.Lex();
1446
1447 // Parse base register.
1448 if (!parsePtrReg(Operands, RegKind))
1449 return MatchOperand_NoMatch;
1450
1451 // Parse ')'.
1452 if (Parser.getTok().isNot(AsmToken::RParen))
1453 return MatchOperand_NoMatch;
1454
1455 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1456 Parser.Lex();
1457
1458 return MatchOperand_Success;
1459}
1460
Jack Carter873c7242013-01-12 01:03:14 +00001461MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001462MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1463 int RegKind) {
1464 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001465 if (getLexer().getKind() == AsmToken::Identifier
1466 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001467 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001468 return MatchOperand_Success;
1469 return MatchOperand_NoMatch;
1470 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001471 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001472 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001473 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001474 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001475 if (!hasConsumedDollar) {
1476 Parser.Lex(); // Eat the '$'
1477 hasConsumedDollar = true;
1478 }
1479 if (getLexer().getKind() == AsmToken::Identifier) {
1480 int RegNum = -1;
1481 std::string RegName = Parser.getTok().getString().lower();
1482 // Match register by name
1483 switch (RegKind) {
1484 case MipsOperand::Kind_GPR32:
1485 case MipsOperand::Kind_GPR64:
1486 RegNum = matchCPURegisterName(RegName);
1487 break;
1488 case MipsOperand::Kind_AFGR64Regs:
1489 case MipsOperand::Kind_FGR64Regs:
1490 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001491 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001492 RegNum = matchFPURegisterName(RegName);
1493 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1494 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001495 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1496 && !isFP64())
1497 if (RegNum != -1 && RegNum %2 != 0)
1498 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001499 break;
1500 case MipsOperand::Kind_FCCRegs:
1501 RegNum = matchFCCRegisterName(RegName);
1502 break;
1503 case MipsOperand::Kind_ACC64DSP:
1504 RegNum = matchACRegisterName(RegName);
1505 break;
1506 default: break; // No match, value is set to -1.
1507 }
1508 // No match found, return _NoMatch to give a chance to other round.
1509 if (RegNum < 0)
1510 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001511
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001512 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1513 if (RegVal == -1)
1514 return MatchOperand_NoMatch;
1515
1516 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1517 Parser.getTok().getLoc());
1518 Op->setRegKind(Kind);
1519 Operands.push_back(Op);
1520 hasConsumedDollar = false;
1521 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001522 return MatchOperand_Success;
1523 } else if (getLexer().getKind() == AsmToken::Integer) {
1524 unsigned RegNum = Parser.getTok().getIntVal();
1525 if (Kind == MipsOperand::Kind_HWRegs) {
1526 if (RegNum != 29)
1527 return MatchOperand_NoMatch;
1528 // Only hwreg 29 is supported, found at index 0.
1529 RegNum = 0;
1530 }
1531 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1532 if (Reg == -1)
1533 return MatchOperand_NoMatch;
1534 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1535 Op->setRegKind(Kind);
1536 Operands.push_back(Op);
1537 hasConsumedDollar = false;
1538 Parser.Lex(); // Eat the register number.
1539 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001540 && (getLexer().is(AsmToken::LParen))) {
1541 // Check if it is indexed addressing operand.
1542 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1543 Parser.Lex(); // Eat the parenthesis.
1544 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1545 return MatchOperand_NoMatch;
1546 if (getLexer().isNot(AsmToken::RParen))
1547 return MatchOperand_NoMatch;
1548 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1549 Parser.Lex();
1550 }
Jack Carter873c7242013-01-12 01:03:14 +00001551 return MatchOperand_Success;
1552 }
1553 return MatchOperand_NoMatch;
1554}
Vladimir Medic64828a12013-07-16 10:07:14 +00001555
Matheus Almeidab74293d2013-10-14 11:49:30 +00001556bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1557 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1558
1559 if (Val < 0)
1560 return false;
1561
1562 switch (Kind) {
1563 default:
1564 return false;
1565 case MipsOperand::Kind_MSA128BRegs:
1566 return Val < 16;
1567 case MipsOperand::Kind_MSA128HRegs:
1568 return Val < 8;
1569 case MipsOperand::Kind_MSA128WRegs:
1570 return Val < 4;
1571 case MipsOperand::Kind_MSA128DRegs:
1572 return Val < 2;
1573 }
1574}
1575
Vladimir Medic8cd17102013-06-20 11:21:49 +00001576MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +00001577MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1578 int RegKind) {
1579 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1580 SMLoc S = Parser.getTok().getLoc();
1581 std::string RegName;
1582
1583 if (Parser.getTok().isNot(AsmToken::Dollar))
1584 return MatchOperand_NoMatch;
1585
1586 switch (RegKind) {
1587 default:
1588 return MatchOperand_ParseFail;
1589 case MipsOperand::Kind_MSA128BRegs:
1590 case MipsOperand::Kind_MSA128HRegs:
1591 case MipsOperand::Kind_MSA128WRegs:
1592 case MipsOperand::Kind_MSA128DRegs:
1593 break;
1594 }
1595
1596 Parser.Lex(); // Eat the '$'.
1597 if (getLexer().getKind() == AsmToken::Identifier)
1598 RegName = Parser.getTok().getString().lower();
1599 else
1600 return MatchOperand_ParseFail;
1601
1602 int RegNum = matchMSA128RegisterName(RegName);
1603
1604 if (RegNum < 0 || RegNum > 31)
1605 return MatchOperand_ParseFail;
1606
1607 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1608 if (RegVal == -1)
1609 return MatchOperand_ParseFail;
1610
1611 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1612 Parser.getTok().getLoc());
1613 Op->setRegKind(Kind);
1614 Operands.push_back(Op);
1615
1616 Parser.Lex(); // Eat the register identifier.
1617
Matheus Almeidab74293d2013-10-14 11:49:30 +00001618 // MSA registers may be suffixed with an index in the form of:
1619 // 1) Immediate expression.
1620 // 2) General Purpose Register.
1621 // Examples:
1622 // 1) copy_s.b $29,$w0[0]
1623 // 2) sld.b $w0,$w1[$1]
1624
1625 if (Parser.getTok().isNot(AsmToken::LBrac))
1626 return MatchOperand_Success;
1627
1628 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1629
1630 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1631 Parser.Lex(); // Parse the '[' token.
1632
1633 if (Parser.getTok().is(AsmToken::Dollar)) {
1634 // This must be a GPR.
1635 MipsOperand *RegOp;
1636 SMLoc VIdx = Parser.getTok().getLoc();
1637 Parser.Lex(); // Parse the '$' token.
1638
1639 // GPR have aliases and we must account for that. Example: $30 == $fp
1640 if (getLexer().getKind() == AsmToken::Integer) {
1641 unsigned RegNum = Parser.getTok().getIntVal();
1642 int Reg = matchRegisterByNumber(
1643 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1644 if (Reg == -1) {
1645 Error(VIdx, "invalid general purpose register");
1646 return MatchOperand_ParseFail;
1647 }
1648
1649 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1650 } else if (getLexer().getKind() == AsmToken::Identifier) {
1651 int RegNum = -1;
1652 std::string RegName = Parser.getTok().getString().lower();
1653
1654 RegNum = matchCPURegisterName(RegName);
1655 if (RegNum == -1) {
1656 Error(VIdx, "general purpose register expected");
1657 return MatchOperand_ParseFail;
1658 }
1659 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1660 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1661 } else
1662 return MatchOperand_ParseFail;
1663
1664 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1665 Operands.push_back(RegOp);
1666 Parser.Lex(); // Eat the register identifier.
1667
1668 if (Parser.getTok().isNot(AsmToken::RBrac))
1669 return MatchOperand_ParseFail;
1670
1671 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1672 Parser.Lex(); // Parse the ']' token.
1673
1674 return MatchOperand_Success;
1675 }
1676
1677 // The index must be a constant expression then.
1678 SMLoc VIdx = Parser.getTok().getLoc();
1679 const MCExpr *ImmVal;
1680
1681 if (getParser().parseExpression(ImmVal))
1682 return MatchOperand_ParseFail;
1683
1684 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1685 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1686 Error(VIdx, "invalid immediate value");
1687 return MatchOperand_ParseFail;
1688 }
1689
1690 SMLoc E = Parser.getTok().getEndLoc();
1691
1692 if (Parser.getTok().isNot(AsmToken::RBrac))
1693 return MatchOperand_ParseFail;
1694
1695 bool insve = Mnemonic->getToken() == "insve.b" ||
1696 Mnemonic->getToken() == "insve.h" ||
1697 Mnemonic->getToken() == "insve.w" ||
1698 Mnemonic->getToken() == "insve.d";
1699
1700 // The second vector index of insve instructions is always 0.
1701 if (insve && Operands.size() > 6) {
1702 if (expr->getValue() != 0) {
1703 Error(VIdx, "immediate value must be 0");
1704 return MatchOperand_ParseFail;
1705 }
1706 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1707 } else
1708 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1709
1710 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1711
1712 Parser.Lex(); // Parse the ']' token.
1713
Jack Carter5dc8ac92013-09-25 23:50:44 +00001714 return MatchOperand_Success;
1715}
1716
1717MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001718MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001719
1720 if (!isMips64())
1721 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001722 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001723}
1724
1725MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001726MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1727 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001728}
Jack Carter873c7242013-01-12 01:03:14 +00001729
Vladimir Medic233dd512013-06-24 10:05:34 +00001730MipsAsmParser::OperandMatchResultTy
1731MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1732
1733 if (isFP64())
1734 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001735 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1736}
1737
1738MipsAsmParser::OperandMatchResultTy
1739MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1740 if (!isFP64())
1741 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001742 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1743}
1744
1745MipsAsmParser::OperandMatchResultTy
1746MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001747 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1748}
1749
Vladimir Medic643b3982013-07-30 10:12:14 +00001750MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001751MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1752 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1753}
1754
1755MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001756MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001757 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001758}
1759
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001760MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001761MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001762 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001763}
1764
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001765MipsAsmParser::OperandMatchResultTy
1766MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1767 // If the first token is not '$' we have an error.
1768 if (Parser.getTok().isNot(AsmToken::Dollar))
1769 return MatchOperand_NoMatch;
1770
1771 SMLoc S = Parser.getTok().getLoc();
1772 Parser.Lex(); // Eat the '$'
1773
1774 const AsmToken &Tok = Parser.getTok(); // Get next token.
1775
1776 if (Tok.isNot(AsmToken::Identifier))
1777 return MatchOperand_NoMatch;
1778
1779 if (!Tok.getIdentifier().startswith("ac"))
1780 return MatchOperand_NoMatch;
1781
1782 StringRef NumString = Tok.getIdentifier().substr(2);
1783
1784 unsigned IntVal;
1785 if (NumString.getAsInteger(10, IntVal))
1786 return MatchOperand_NoMatch;
1787
1788 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1789
1790 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1791 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1792 Operands.push_back(Op);
1793
1794 Parser.Lex(); // Eat the register number.
1795 return MatchOperand_Success;
1796}
1797
1798MipsAsmParser::OperandMatchResultTy
1799MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1800 // If the first token is not '$' we have an error.
1801 if (Parser.getTok().isNot(AsmToken::Dollar))
1802 return MatchOperand_NoMatch;
1803
1804 SMLoc S = Parser.getTok().getLoc();
1805 Parser.Lex(); // Eat the '$'
1806
1807 const AsmToken &Tok = Parser.getTok(); // Get next token.
1808
1809 if (Tok.isNot(AsmToken::Identifier))
1810 return MatchOperand_NoMatch;
1811
1812 if (!Tok.getIdentifier().startswith("ac"))
1813 return MatchOperand_NoMatch;
1814
1815 StringRef NumString = Tok.getIdentifier().substr(2);
1816
1817 unsigned IntVal;
1818 if (NumString.getAsInteger(10, IntVal))
1819 return MatchOperand_NoMatch;
1820
1821 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1822
1823 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1824 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1825 Operands.push_back(Op);
1826
1827 Parser.Lex(); // Eat the register number.
1828 return MatchOperand_Success;
1829}
1830
Vladimir Medic05bcde62013-09-16 10:29:42 +00001831MipsAsmParser::OperandMatchResultTy
1832MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1833 // If the first token is not '$' we have an error.
1834 if (Parser.getTok().isNot(AsmToken::Dollar))
1835 return MatchOperand_NoMatch;
1836
1837 SMLoc S = Parser.getTok().getLoc();
1838 Parser.Lex(); // Eat the '$'
1839
1840 const AsmToken &Tok = Parser.getTok(); // Get next token.
1841
1842 if (Tok.isNot(AsmToken::Integer))
1843 return MatchOperand_NoMatch;
1844
1845 unsigned IntVal = Tok.getIntVal();
1846
1847 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1848
1849 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1850 Op->setRegKind(MipsOperand::Kind_COP2);
1851 Operands.push_back(Op);
1852
1853 Parser.Lex(); // Eat the register number.
1854 return MatchOperand_Success;
1855}
1856
Jack Carter5dc8ac92013-09-25 23:50:44 +00001857MipsAsmParser::OperandMatchResultTy
1858MipsAsmParser::parseMSA128BRegs(
1859 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1860 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
1861}
1862
1863MipsAsmParser::OperandMatchResultTy
1864MipsAsmParser::parseMSA128HRegs(
1865 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1866 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
1867}
1868
1869MipsAsmParser::OperandMatchResultTy
1870MipsAsmParser::parseMSA128WRegs(
1871 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1872 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
1873}
1874
1875MipsAsmParser::OperandMatchResultTy
1876MipsAsmParser::parseMSA128DRegs(
1877 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1878 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
1879}
1880
Jack Carterd0bd6422013-04-18 00:41:53 +00001881bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001882 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001883
1884 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1885 if (Sym) {
1886 SMLoc S = Parser.getTok().getLoc();
1887 const MCExpr *Expr;
1888 if (Sym->isVariable())
1889 Expr = Sym->getVariableValue();
1890 else
1891 return false;
1892 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001893 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001894 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1895 const StringRef DefSymbol = Ref->getSymbol().getName();
1896 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001897 int RegNum = -1;
1898 APInt IntVal(32, -1);
1899 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1900 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001901 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001902 ? Mips::GPR64RegClassID
1903 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001904 else {
1905 // Lookup for the register with the corresponding name.
1906 switch (Kind) {
1907 case MipsOperand::Kind_AFGR64Regs:
1908 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001909 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001910 break;
1911 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001912 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001913 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001914 case MipsOperand::Kind_GPR64:
1915 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001916 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001917 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001918 break;
1919 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001920 if (RegNum > -1)
1921 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001922 }
Jack Carterd76b2372013-03-21 21:44:16 +00001923 if (RegNum > -1) {
1924 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001925 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1926 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001927 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001928 Operands.push_back(op);
1929 return true;
1930 }
1931 }
1932 } else if (Expr->getKind() == MCExpr::Constant) {
1933 Parser.Lex();
1934 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001935 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001936 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001937 Operands.push_back(op);
1938 return true;
1939 }
1940 }
1941 return false;
1942}
Jack Carterd0bd6422013-04-18 00:41:53 +00001943
Jack Carter873c7242013-01-12 01:03:14 +00001944MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001945MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001946 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001947}
1948
1949MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001950MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001951 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001952}
1953
Vladimir Medic2b953d02013-10-01 09:48:56 +00001954MipsAsmParser::OperandMatchResultTy
1955MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1956 const MCExpr *IdVal;
1957 // If the first token is '$' we may have register operand.
1958 if (Parser.getTok().is(AsmToken::Dollar))
1959 return MatchOperand_NoMatch;
1960 SMLoc S = Parser.getTok().getLoc();
1961 if (getParser().parseExpression(IdVal))
1962 return MatchOperand_ParseFail;
1963 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
1964 assert( MCE && "Unexpected MCExpr type.");
1965 int64_t Val = MCE->getValue();
1966 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1967 Operands.push_back(MipsOperand::CreateImm(
1968 MCConstantExpr::Create(0 - Val, getContext()), S, E));
1969 return MatchOperand_Success;
1970}
1971
Jack Carterdc1e35d2012-09-06 20:00:02 +00001972MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1973
1974 MCSymbolRefExpr::VariantKind VK
1975 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1976 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1977 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1978 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1979 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1980 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1981 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1982 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1983 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1984 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1985 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1986 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1987 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1988 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1989 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1990 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1991 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1992 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1993 .Default(MCSymbolRefExpr::VK_None);
1994
1995 return VK;
1996}
Jack Cartera63b16a2012-09-07 00:23:42 +00001997
Rafael Espindola870c4e92012-01-11 03:56:41 +00001998bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001999ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00002000 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002001 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002002 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002003 Parser.eatToEndOfStatement();
2004 return Error(NameLoc, "Unknown instruction");
2005 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002006 // First operand in MCInst is instruction mnemonic.
2007 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002008
2009 // Read the remaining operands.
2010 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2011 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002012 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002013 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002014 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002015 return Error(Loc, "unexpected token in argument list");
2016 }
2017
Jack Carterd0bd6422013-04-18 00:41:53 +00002018 while (getLexer().is(AsmToken::Comma)) {
2019 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002020 // Parse and remember the operand.
2021 if (ParseOperand(Operands, Name)) {
2022 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002023 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002024 return Error(Loc, "unexpected token in argument list");
2025 }
2026 }
2027 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002028 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2029 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002030 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002031 return Error(Loc, "unexpected token in argument list");
2032 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002033 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002034 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002035}
2036
Jack Carter0b744b32012-10-04 02:29:46 +00002037bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002038 SMLoc Loc = getLexer().getLoc();
2039 Parser.eatToEndOfStatement();
2040 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002041}
2042
2043bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002044 // Line should look like: ".set noat".
2045 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002046 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002047 // eat noat
2048 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002049 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002050 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2051 reportParseError("unexpected token in statement");
2052 return false;
2053 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002054 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002055 return false;
2056}
Jack Carterd0bd6422013-04-18 00:41:53 +00002057
Jack Carter0b744b32012-10-04 02:29:46 +00002058bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002059 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002060 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002061 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002062 getParser().Lex();
2063 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002064 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002065 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002066 return false;
2067 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002068 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002069 if (getLexer().isNot(AsmToken::Dollar)) {
2070 reportParseError("unexpected token in statement");
2071 return false;
2072 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002073 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002074 const AsmToken &Reg = Parser.getTok();
2075 if (Reg.is(AsmToken::Identifier)) {
2076 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2077 } else if (Reg.is(AsmToken::Integer)) {
2078 AtRegNo = Reg.getIntVal();
2079 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002080 reportParseError("unexpected token in statement");
2081 return false;
2082 }
Jack Carter1ac53222013-02-20 23:11:17 +00002083
Jack Carterd0bd6422013-04-18 00:41:53 +00002084 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002085 reportParseError("unexpected token in statement");
2086 return false;
2087 }
2088
2089 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002090 reportParseError("unexpected token in statement");
2091 return false;
2092 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002093 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002094
2095 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2096 reportParseError("unexpected token in statement");
2097 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002098 }
2099 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002100 return false;
2101 } else {
2102 reportParseError("unexpected token in statement");
2103 return false;
2104 }
2105}
2106
2107bool MipsAsmParser::parseSetReorderDirective() {
2108 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002109 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002110 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2111 reportParseError("unexpected token in statement");
2112 return false;
2113 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002114 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002115 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002116 return false;
2117}
2118
2119bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002120 Parser.Lex();
2121 // If this is not the end of the statement, report an error.
2122 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2123 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002124 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002125 }
2126 Options.setNoreorder();
2127 Parser.Lex(); // Consume the EndOfStatement.
2128 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002129}
2130
2131bool MipsAsmParser::parseSetMacroDirective() {
2132 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002133 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2135 reportParseError("unexpected token in statement");
2136 return false;
2137 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002138 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002139 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002140 return false;
2141}
2142
2143bool MipsAsmParser::parseSetNoMacroDirective() {
2144 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002145 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002146 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2147 reportParseError("`noreorder' must be set before `nomacro'");
2148 return false;
2149 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002150 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002151 reportParseError("`noreorder' must be set before `nomacro'");
2152 return false;
2153 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002154 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002155 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002156 return false;
2157}
Jack Carterd76b2372013-03-21 21:44:16 +00002158
2159bool MipsAsmParser::parseSetAssignment() {
2160 StringRef Name;
2161 const MCExpr *Value;
2162
2163 if (Parser.parseIdentifier(Name))
2164 reportParseError("expected identifier after .set");
2165
2166 if (getLexer().isNot(AsmToken::Comma))
2167 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002168 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002169
Jack Carter02593002013-05-28 22:21:05 +00002170 if (getLexer().is(AsmToken::Dollar)) {
2171 MCSymbol *Symbol;
2172 SMLoc DollarLoc = getLexer().getLoc();
2173 // Consume the dollar sign, and check for a following identifier.
2174 Parser.Lex();
2175 // We have a '$' followed by something, make sure they are adjacent.
2176 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2177 return true;
2178 StringRef Res = StringRef(DollarLoc.getPointer(),
2179 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2180 Symbol = getContext().GetOrCreateSymbol(Res);
2181 Parser.Lex();
2182 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
2183 getContext());
2184 } else if (Parser.parseExpression(Value))
2185 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002186
Jack Carterd0bd6422013-04-18 00:41:53 +00002187 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002188 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002189 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002190 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002191 Sym = getContext().GetOrCreateSymbol(Name);
2192 Sym->setVariableValue(Value);
2193
2194 return false;
2195}
Jack Carterd0bd6422013-04-18 00:41:53 +00002196
Jack Carter0b744b32012-10-04 02:29:46 +00002197bool MipsAsmParser::parseDirectiveSet() {
2198
Jack Carterd0bd6422013-04-18 00:41:53 +00002199 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002200 const AsmToken &Tok = Parser.getTok();
2201
2202 if (Tok.getString() == "noat") {
2203 return parseSetNoAtDirective();
2204 } else if (Tok.getString() == "at") {
2205 return parseSetAtDirective();
2206 } else if (Tok.getString() == "reorder") {
2207 return parseSetReorderDirective();
2208 } else if (Tok.getString() == "noreorder") {
2209 return parseSetNoReorderDirective();
2210 } else if (Tok.getString() == "macro") {
2211 return parseSetMacroDirective();
2212 } else if (Tok.getString() == "nomacro") {
2213 return parseSetNoMacroDirective();
2214 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002215 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002216 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002217 return false;
2218 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002219 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002220 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002221 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002222 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002223 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002224 parseSetAssignment();
2225 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002226 }
Jack Carter07c818d2013-01-25 01:31:34 +00002227
Jack Carter0b744b32012-10-04 02:29:46 +00002228 return true;
2229}
2230
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002231bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2232 MCAsmParser &Parser = getParser();
2233 StringRef Name;
2234 if (Parser.parseIdentifier(Name))
2235 reportParseError("expected identifier");
2236
2237 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2238 if (getLexer().isNot(AsmToken::Comma))
2239 return TokError("unexpected token");
2240 Lex();
2241
2242 int64_t Flags = 0;
2243 if (Parser.parseAbsoluteExpression(Flags))
2244 return TokError("unexpected token");
2245
Rafael Espindolaa17151a2013-10-08 13:08:17 +00002246 getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002247 return false;
2248}
2249
2250bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2251 int64_t Flags = 0;
2252 if (Parser.parseAbsoluteExpression(Flags))
2253 return TokError("unexpected token");
2254
Rafael Espindolaa17151a2013-10-08 13:08:17 +00002255 getTargetStreamer().emitMipsHackELFFlags(Flags);
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002256 return false;
2257}
2258
Jack Carter07c818d2013-01-25 01:31:34 +00002259/// parseDirectiveWord
2260/// ::= .word [ expression (, expression)* ]
2261bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2262 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2263 for (;;) {
2264 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002265 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002266 return true;
2267
2268 getParser().getStreamer().EmitValue(Value, Size);
2269
2270 if (getLexer().is(AsmToken::EndOfStatement))
2271 break;
2272
2273 // FIXME: Improve diagnostic.
2274 if (getLexer().isNot(AsmToken::Comma))
2275 return Error(L, "unexpected token in directive");
2276 Parser.Lex();
2277 }
2278 }
2279
2280 Parser.Lex();
2281 return false;
2282}
2283
Jack Carter0b744b32012-10-04 02:29:46 +00002284bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00002285
Jack Carter07c818d2013-01-25 01:31:34 +00002286 StringRef IDVal = DirectiveID.getString();
2287
Jack Carterd0bd6422013-04-18 00:41:53 +00002288 if (IDVal == ".ent") {
2289 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002290 Parser.Lex();
2291 return false;
2292 }
2293
Jack Carter07c818d2013-01-25 01:31:34 +00002294 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002295 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002296 Parser.Lex();
2297 return false;
2298 }
2299
Jack Carter07c818d2013-01-25 01:31:34 +00002300 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002301 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002302 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002303 return false;
2304 }
2305
Jack Carter07c818d2013-01-25 01:31:34 +00002306 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002307 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002308 }
2309
Jack Carter07c818d2013-01-25 01:31:34 +00002310 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002311 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002312 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002313 return false;
2314 }
2315
Jack Carter07c818d2013-01-25 01:31:34 +00002316 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002317 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002318 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002319 return false;
2320 }
2321
Jack Carter07c818d2013-01-25 01:31:34 +00002322 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002323 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002324 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002325 return false;
2326 }
2327
Jack Carter07c818d2013-01-25 01:31:34 +00002328 if (IDVal == ".word") {
2329 parseDirectiveWord(4, DirectiveID.getLoc());
2330 return false;
2331 }
2332
Rafael Espindolaac4ad252013-10-05 16:42:21 +00002333 if (IDVal == ".mips_hack_stocg")
2334 return parseDirectiveMipsHackStocg();
2335
2336 if (IDVal == ".mips_hack_elf_flags")
2337 return parseDirectiveMipsHackELFFlags();
2338
Rafael Espindola870c4e92012-01-11 03:56:41 +00002339 return true;
2340}
2341
Rafael Espindola870c4e92012-01-11 03:56:41 +00002342extern "C" void LLVMInitializeMipsAsmParser() {
2343 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2344 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2345 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2346 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2347}
Jack Carterb4dbc172012-09-05 23:34:03 +00002348
2349#define GET_REGISTER_MATCHER
2350#define GET_MATCHER_IMPLEMENTATION
2351#include "MipsGenAsmMatcher.inc"