blob: 5b77d87350a8862262796b9a5d8fa6fc036dff60 [file] [log] [blame]
Jia Liu9f610112012-02-17 08:55:11 +00001//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
Rafael Espindola870c4e92012-01-11 03:56:41 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/MipsMCTargetDesc.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000011#include "MipsRegisterInfo.h"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCInst.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000016#include "llvm/MC/MCParser/MCAsmLexer.h"
17#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000018#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSubtargetInfo.h"
20#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000021#include "llvm/MC/MCTargetAsmParser.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000022#include "llvm/Support/TargetRegistry.h"
Jack Carter02593002013-05-28 22:21:05 +000023#include "llvm/ADT/APInt.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000024
25using namespace llvm;
26
Joey Gouly0e76fa72013-09-12 10:28:05 +000027namespace llvm {
28class MCInstrInfo;
29}
30
Rafael Espindola870c4e92012-01-11 03:56:41 +000031namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000032class MipsAssemblerOptions {
33public:
34 MipsAssemblerOptions():
35 aTReg(1), reorder(true), macro(true) {
36 }
Jack Carterb4dbc172012-09-05 23:34:03 +000037
Jack Carter0b744b32012-10-04 02:29:46 +000038 unsigned getATRegNum() {return aTReg;}
39 bool setATReg(unsigned Reg);
40
41 bool isReorder() {return reorder;}
42 void setReorder() {reorder = true;}
43 void setNoreorder() {reorder = false;}
44
45 bool isMacro() {return macro;}
46 void setMacro() {macro = true;}
47 void setNomacro() {macro = false;}
48
49private:
50 unsigned aTReg;
51 bool reorder;
52 bool macro;
53};
54}
55
56namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000057class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000058
Jack Carterb4dbc172012-09-05 23:34:03 +000059 MCSubtargetInfo &STI;
60 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000061 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000062 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000063
Akira Hatanaka7605630c2012-08-17 20:16:42 +000064#define GET_ASSEMBLER_HEADER
65#include "MipsGenAsmMatcher.inc"
66
Chad Rosier49963552012-10-13 00:26:04 +000067 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +000068 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000069 MCStreamer &Out, unsigned &ErrorInfo,
70 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000071
72 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
73
Chad Rosierf0e87202012-10-25 20:41:34 +000074 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
75 SMLoc NameLoc,
Akira Hatanaka7605630c2012-08-17 20:16:42 +000076 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000077
78 bool ParseDirective(AsmToken DirectiveID);
79
Jack Carterb4dbc172012-09-05 23:34:03 +000080 MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +000081 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
82 int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000083
84 MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +000085 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
86 int RegKind);
87
88 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +000089 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
90
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000091 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
92
93 MipsAsmParser::OperandMatchResultTy
94 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
95
Jack Carter873c7242013-01-12 01:03:14 +000096 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +000097 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000098
99 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000100 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000101
102 MipsAsmParser::OperandMatchResultTy
103 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
104
105 MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +0000106 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000107
Vladimir Medic233dd512013-06-24 10:05:34 +0000108 MipsAsmParser::OperandMatchResultTy
109 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
110
111 MipsAsmParser::OperandMatchResultTy
112 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
113
114 MipsAsmParser::OperandMatchResultTy
115 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
116
Vladimir Medic643b3982013-07-30 10:12:14 +0000117 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000118 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
119
120 MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +0000121 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
122
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000123 MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000124 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000125
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000126 MipsAsmParser::OperandMatchResultTy
127 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
128
129 MipsAsmParser::OperandMatchResultTy
130 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
131
Vladimir Medic05bcde62013-09-16 10:29:42 +0000132 MipsAsmParser::OperandMatchResultTy
133 parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
134
Jack Carter5dc8ac92013-09-25 23:50:44 +0000135 MipsAsmParser::OperandMatchResultTy
136 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
137
138 MipsAsmParser::OperandMatchResultTy
139 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
140
141 MipsAsmParser::OperandMatchResultTy
142 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
143
144 MipsAsmParser::OperandMatchResultTy
145 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
146
Jack Carterd76b2372013-03-21 21:44:16 +0000147 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000148 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000149
Jack Carterb4dbc172012-09-05 23:34:03 +0000150 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
151 StringRef Mnemonic);
152
Jack Carter873c7242013-01-12 01:03:14 +0000153 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000154
155 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000156 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000157
Jack Carter30a59822012-10-04 04:03:53 +0000158 bool needsExpansion(MCInst &Inst);
159
160 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000161 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000162 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000163 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000164 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
165 SmallVectorImpl<MCInst> &Instructions);
166 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000168 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
169 SmallVectorImpl<MCInst> &Instructions,
170 bool isLoad,bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000171 bool reportParseError(StringRef ErrorMsg);
172
Jack Carterb5cf5902013-04-17 00:18:04 +0000173 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000174 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000175
Jack Carterb5cf5902013-04-17 00:18:04 +0000176 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
177
178 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000179 bool parseDirectiveSet();
180
181 bool parseSetAtDirective();
182 bool parseSetNoAtDirective();
183 bool parseSetMacroDirective();
184 bool parseSetNoMacroDirective();
185 bool parseSetReorderDirective();
186 bool parseSetNoReorderDirective();
187
Jack Carterd76b2372013-03-21 21:44:16 +0000188 bool parseSetAssignment();
189
Jack Carter07c818d2013-01-25 01:31:34 +0000190 bool parseDirectiveWord(unsigned Size, SMLoc L);
191
Jack Carterdc1e35d2012-09-06 20:00:02 +0000192 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000193
Jack Carterb4dbc172012-09-05 23:34:03 +0000194 bool isMips64() const {
195 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
196 }
197
Jack Cartera63b16a2012-09-07 00:23:42 +0000198 bool isFP64() const {
199 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
200 }
201
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000202 bool isN64() const {
203 return STI.getFeatureBits() & Mips::FeatureN64;
204 }
205
Jack Carter873c7242013-01-12 01:03:14 +0000206 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000207
Jack Carter1ac53222013-02-20 23:11:17 +0000208 int matchCPURegisterName(StringRef Symbol);
209
Jack Carter873c7242013-01-12 01:03:14 +0000210 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000211
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000212 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000213
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000214 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000215
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000216 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000217
Jack Carter5dc8ac92013-09-25 23:50:44 +0000218 int matchMSA128RegisterName(StringRef Name);
219
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000220 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000221
Jack Carterd0bd6422013-04-18 00:41:53 +0000222 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000223
Jack Carter1ac53222013-02-20 23:11:17 +0000224 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000225
226 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
227 SmallVectorImpl<MCInst> &Instructions);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000228public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000229 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
230 const MCInstrInfo &MII)
231 : MCTargetAsmParser(), STI(sti), Parser(parser),
232 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000233 // Initialize the set of available features.
234 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000235 }
236
Jack Carterb4dbc172012-09-05 23:34:03 +0000237 MCAsmParser &getParser() const { return Parser; }
238 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
239
Rafael Espindola870c4e92012-01-11 03:56:41 +0000240};
241}
242
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000243namespace {
244
245/// MipsOperand - Instances of this class represent a parsed Mips machine
246/// instruction.
247class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000248
Jack Carter873c7242013-01-12 01:03:14 +0000249public:
250 enum RegisterKind {
251 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000252 Kind_GPR32,
253 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000254 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000255 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000256 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000257 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000258 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000259 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000260 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000261 Kind_ACC64DSP,
262 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000263 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000264 Kind_COP2,
265 Kind_MSA128BRegs,
266 Kind_MSA128HRegs,
267 Kind_MSA128WRegs,
268 Kind_MSA128DRegs
Jack Carter873c7242013-01-12 01:03:14 +0000269 };
270
271private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000272 enum KindTy {
273 k_CondCode,
274 k_CoprocNum,
275 k_Immediate,
276 k_Memory,
277 k_PostIndexRegister,
278 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000279 k_PtrReg,
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000280 k_Token
281 } Kind;
282
283 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000284
Eric Christopher8996c5d2013-03-15 00:42:55 +0000285 struct Token {
286 const char *Data;
287 unsigned Length;
288 };
289
290 struct RegOp {
291 unsigned RegNum;
292 RegisterKind Kind;
293 };
294
295 struct ImmOp {
296 const MCExpr *Val;
297 };
298
299 struct MemOp {
300 unsigned Base;
301 const MCExpr *Off;
302 };
303
Jack Carterb4dbc172012-09-05 23:34:03 +0000304 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000305 struct Token Tok;
306 struct RegOp Reg;
307 struct ImmOp Imm;
308 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000309 };
310
311 SMLoc StartLoc, EndLoc;
312
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000313public:
314 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000315 assert(N == 1 && "Invalid number of operands!");
316 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000317 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000318
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000319 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
320 assert(N == 1 && "Invalid number of operands!");
321 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
322 }
323
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000324 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
Jack Carterb4dbc172012-09-05 23:34:03 +0000325 // Add as immediate when possible. Null MCExpr = 0.
326 if (Expr == 0)
327 Inst.addOperand(MCOperand::CreateImm(0));
328 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
329 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
330 else
331 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000332 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000333
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000334 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000335 assert(N == 1 && "Invalid number of operands!");
336 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000337 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000338 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000339
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000340 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000341 assert(N == 2 && "Invalid number of operands!");
342
343 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
344
345 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000346 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000347 }
348
349 bool isReg() const { return Kind == k_Register; }
350 bool isImm() const { return Kind == k_Immediate; }
351 bool isToken() const { return Kind == k_Token; }
352 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000353 bool isPtrReg() const { return Kind == k_PtrReg; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000354
355 StringRef getToken() const {
356 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000357 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000358 }
359
360 unsigned getReg() const {
361 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000362 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000363 }
364
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000365 unsigned getPtrReg() const {
366 assert((Kind == k_PtrReg) && "Invalid access!");
367 return Reg.RegNum;
368 }
369
Jack Carter873c7242013-01-12 01:03:14 +0000370 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000371 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000372 Reg.Kind = RegKind;
373 }
374
Jack Carterb4dbc172012-09-05 23:34:03 +0000375 const MCExpr *getImm() const {
376 assert((Kind == k_Immediate) && "Invalid access!");
377 return Imm.Val;
378 }
379
Jack Carterdc1e35d2012-09-06 20:00:02 +0000380 unsigned getMemBase() const {
381 assert((Kind == k_Memory) && "Invalid access!");
382 return Mem.Base;
383 }
384
385 const MCExpr *getMemOff() const {
386 assert((Kind == k_Memory) && "Invalid access!");
387 return Mem.Off;
388 }
389
Jack Carterb4dbc172012-09-05 23:34:03 +0000390 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
391 MipsOperand *Op = new MipsOperand(k_Token);
392 Op->Tok.Data = Str.data();
393 Op->Tok.Length = Str.size();
394 Op->StartLoc = S;
395 Op->EndLoc = S;
396 return Op;
397 }
398
399 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
400 MipsOperand *Op = new MipsOperand(k_Register);
401 Op->Reg.RegNum = RegNum;
402 Op->StartLoc = S;
403 Op->EndLoc = E;
404 return Op;
405 }
406
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000407 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
408 MipsOperand *Op = new MipsOperand(k_PtrReg);
409 Op->Reg.RegNum = RegNum;
410 Op->StartLoc = S;
411 Op->EndLoc = E;
412 return Op;
413 }
414
Jack Carterb4dbc172012-09-05 23:34:03 +0000415 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
416 MipsOperand *Op = new MipsOperand(k_Immediate);
417 Op->Imm.Val = Val;
418 Op->StartLoc = S;
419 Op->EndLoc = E;
420 return Op;
421 }
422
Jack Carterdc1e35d2012-09-06 20:00:02 +0000423 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
424 SMLoc S, SMLoc E) {
425 MipsOperand *Op = new MipsOperand(k_Memory);
426 Op->Mem.Base = Base;
427 Op->Mem.Off = Off;
428 Op->StartLoc = S;
429 Op->EndLoc = E;
430 return Op;
431 }
432
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000433 bool isGPR32Asm() const {
434 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000435 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000436 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000437 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
438 }
439
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000440 bool isGPR64Asm() const {
441 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000442 }
Jack Carter873c7242013-01-12 01:03:14 +0000443
444 bool isHWRegsAsm() const {
445 assert((Kind == k_Register) && "Invalid access!");
446 return Reg.Kind == Kind_HWRegs;
447 }
Jack Carter873c7242013-01-12 01:03:14 +0000448
Jack Carter873c7242013-01-12 01:03:14 +0000449 bool isCCRAsm() const {
450 assert((Kind == k_Register) && "Invalid access!");
451 return Reg.Kind == Kind_CCRRegs;
452 }
453
Vladimir Medic233dd512013-06-24 10:05:34 +0000454 bool isAFGR64Asm() const {
455 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
456 }
457
458 bool isFGR64Asm() const {
459 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
460 }
461
462 bool isFGR32Asm() const {
463 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
464 }
465
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000466 bool isFGRH32Asm() const {
467 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
468 }
469
Vladimir Medic643b3982013-07-30 10:12:14 +0000470 bool isFCCRegsAsm() const {
471 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
472 }
473
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000474 bool isACC64DSPAsm() const {
475 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000476 }
477
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000478 bool isLO32DSPAsm() const {
479 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
480 }
481
482 bool isHI32DSPAsm() const {
483 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
484 }
485
Vladimir Medic05bcde62013-09-16 10:29:42 +0000486 bool isCOP2Asm() const {
487 return Kind == k_Register && Reg.Kind == Kind_COP2;
488 }
489
Jack Carter5dc8ac92013-09-25 23:50:44 +0000490 bool isMSA128BAsm() const {
491 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
492 }
493
494 bool isMSA128HAsm() const {
495 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
496 }
497
498 bool isMSA128WAsm() const {
499 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
500 }
501
502 bool isMSA128DAsm() const {
503 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
504 }
505
Jack Carterb4dbc172012-09-05 23:34:03 +0000506 /// getStartLoc - Get the location of the first token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000507 SMLoc getStartLoc() const {
508 return StartLoc;
509 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000510 /// getEndLoc - Get the location of the last token of this operand.
Jack Carterd0bd6422013-04-18 00:41:53 +0000511 SMLoc getEndLoc() const {
512 return EndLoc;
513 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000514
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000515 virtual void print(raw_ostream &OS) const {
516 llvm_unreachable("unimplemented!");
517 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000518}; // class MipsOperand
519} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000520
Jack Carter9e65aa32013-03-22 00:05:30 +0000521namespace llvm {
522extern const MCInstrDesc MipsInsts[];
523}
524static const MCInstrDesc &getInstDesc(unsigned Opcode) {
525 return MipsInsts[Opcode];
526}
527
528bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000529 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000530 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
531 Inst.setLoc(IDLoc);
Jack Carterc15c1d22013-04-25 23:31:35 +0000532 if (MCID.hasDelaySlot() && Options.isReorder()) {
533 // If this instruction has a delay slot and .set reorder is active,
534 // emit a NOP after it.
535 Instructions.push_back(Inst);
536 MCInst NopInst;
537 NopInst.setOpcode(Mips::SLL);
538 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
539 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
540 NopInst.addOperand(MCOperand::CreateImm(0));
541 Instructions.push_back(NopInst);
542 return false;
543 }
544
Jack Carter9e65aa32013-03-22 00:05:30 +0000545 if (MCID.mayLoad() || MCID.mayStore()) {
546 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000547 // reference or immediate we may have to expand instructions.
548 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000549 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Jack Carterd0bd6422013-04-18 00:41:53 +0000550 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
551 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000552 MCOperand &Op = Inst.getOperand(i);
553 if (Op.isImm()) {
554 int MemOffset = Op.getImm();
555 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000556 // Offset can't exceed 16bit value.
557 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000558 return false;
559 }
560 } else if (Op.isExpr()) {
561 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000562 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000563 const MCSymbolRefExpr *SR =
Jack Carterb5cf5902013-04-17 00:18:04 +0000564 static_cast<const MCSymbolRefExpr*>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000565 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000566 // Expand symbol.
567 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000568 return false;
569 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000570 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000571 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000572 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000573 }
574 }
575 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000576 } // for
577 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000578
579 if (needsExpansion(Inst))
580 expandInstruction(Inst, IDLoc, Instructions);
581 else
582 Instructions.push_back(Inst);
583
584 return false;
585}
586
Jack Carter30a59822012-10-04 04:03:53 +0000587bool MipsAsmParser::needsExpansion(MCInst &Inst) {
588
Jack Carterd0bd6422013-04-18 00:41:53 +0000589 switch (Inst.getOpcode()) {
590 case Mips::LoadImm32Reg:
591 case Mips::LoadAddr32Imm:
592 case Mips::LoadAddr32Reg:
593 return true;
594 default:
595 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000596 }
597}
Jack Carter92995f12012-10-06 00:53:28 +0000598
Jack Carter30a59822012-10-04 04:03:53 +0000599void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000600 SmallVectorImpl<MCInst> &Instructions) {
601 switch (Inst.getOpcode()) {
602 case Mips::LoadImm32Reg:
603 return expandLoadImm(Inst, IDLoc, Instructions);
604 case Mips::LoadAddr32Imm:
605 return expandLoadAddressImm(Inst, IDLoc, Instructions);
606 case Mips::LoadAddr32Reg:
607 return expandLoadAddressReg(Inst, IDLoc, Instructions);
608 }
Jack Carter30a59822012-10-04 04:03:53 +0000609}
Jack Carter92995f12012-10-06 00:53:28 +0000610
Jack Carter30a59822012-10-04 04:03:53 +0000611void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000612 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000613 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000614 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000615 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000616 const MCOperand &RegOp = Inst.getOperand(0);
617 assert(RegOp.isReg() && "expected register operand kind");
618
619 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000620 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000621 if (0 <= ImmValue && ImmValue <= 65535) {
622 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000623 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000624 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000625 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000626 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000627 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000628 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000629 } else if (ImmValue < 0 && ImmValue >= -32768) {
630 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000631 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000632 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000633 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000634 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000635 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000636 Instructions.push_back(tmpInst);
637 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000638 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000639 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000640 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000641 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000642 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
643 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000644 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000645 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000646 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000647 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
648 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
649 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
650 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000651 Instructions.push_back(tmpInst);
652 }
653}
Jack Carter92995f12012-10-06 00:53:28 +0000654
Jack Carter543fdf82012-10-09 23:29:45 +0000655void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000656 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000657 MCInst tmpInst;
658 const MCOperand &ImmOp = Inst.getOperand(2);
659 assert(ImmOp.isImm() && "expected immediate operand kind");
660 const MCOperand &SrcRegOp = Inst.getOperand(1);
661 assert(SrcRegOp.isReg() && "expected register operand kind");
662 const MCOperand &DstRegOp = Inst.getOperand(0);
663 assert(DstRegOp.isReg() && "expected register operand kind");
664 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000665 if (-32768 <= ImmValue && ImmValue <= 65535) {
666 // For -32768 <= j <= 65535.
667 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000668 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000669 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
670 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
671 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
672 Instructions.push_back(tmpInst);
673 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000674 // For any other value of j that is representable as a 32-bit integer.
675 // la d,j(s) => lui d,hi16(j)
676 // ori d,d,lo16(j)
677 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000678 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000679 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
680 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
681 Instructions.push_back(tmpInst);
682 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000683 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000684 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
685 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
686 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
687 Instructions.push_back(tmpInst);
688 tmpInst.clear();
689 tmpInst.setOpcode(Mips::ADDu);
690 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
691 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
692 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
693 Instructions.push_back(tmpInst);
694 }
695}
696
697void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000698 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000699 MCInst tmpInst;
700 const MCOperand &ImmOp = Inst.getOperand(1);
701 assert(ImmOp.isImm() && "expected immediate operand kind");
702 const MCOperand &RegOp = Inst.getOperand(0);
703 assert(RegOp.isReg() && "expected register operand kind");
704 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000705 if (-32768 <= ImmValue && ImmValue <= 65535) {
706 // For -32768 <= j <= 65535.
707 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000708 tmpInst.setOpcode(Mips::ADDiu);
709 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000710 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000711 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
712 Instructions.push_back(tmpInst);
713 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000714 // For any other value of j that is representable as a 32-bit integer.
715 // la d,j => lui d,hi16(j)
716 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000717 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000718 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
719 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
720 Instructions.push_back(tmpInst);
721 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000722 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000723 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
724 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
725 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
726 Instructions.push_back(tmpInst);
727 }
728}
729
Jack Carter9e65aa32013-03-22 00:05:30 +0000730void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000731 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000732 const MCSymbolRefExpr *SR;
733 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000734 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000735 const MCExpr *ExprOffset;
736 unsigned TmpRegNum;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000737 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
738 : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000739 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000740 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
741 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000742 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000743 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
744 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000745 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000746 if (isImmOpnd) {
747 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
748 ImmOffset = Inst.getOperand(2).getImm();
749 LoOffset = ImmOffset & 0x0000ffff;
750 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000751 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000752 if (LoOffset & 0x8000)
753 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000754 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000755 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000756 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000757 TempInst.setLoc(IDLoc);
758 // 1st instruction in expansion is LUi. For load instruction we can use
759 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000760 // but for stores we must use $at.
761 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000762 TempInst.setOpcode(Mips::LUi);
763 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
764 if (isImmOpnd)
765 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
766 else {
767 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
768 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000769 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
770 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
771 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000772 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000773 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000774 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000775 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000776 }
777 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000778 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000779 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000780 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000781 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000782 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000783 TempInst.setOpcode(Mips::ADDu);
784 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
785 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
786 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
787 Instructions.push_back(TempInst);
788 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000789 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000790 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000791 TempInst.setOpcode(Inst.getOpcode());
792 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
793 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
794 if (isImmOpnd)
795 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
796 else {
797 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000798 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
799 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
800 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000801 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000802 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000803 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000804 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000805 }
806 }
807 Instructions.push_back(TempInst);
808 TempInst.clear();
809}
810
Rafael Espindola870c4e92012-01-11 03:56:41 +0000811bool MipsAsmParser::
Chad Rosier49963552012-10-13 00:26:04 +0000812MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Rafael Espindola870c4e92012-01-11 03:56:41 +0000813 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +0000814 MCStreamer &Out, unsigned &ErrorInfo,
815 bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000816 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000817 SmallVector<MCInst, 8> Instructions;
Chad Rosier2f480a82012-10-12 22:53:36 +0000818 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
Chad Rosier49963552012-10-13 00:26:04 +0000819 MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000820
821 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000822 default:
823 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000824 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000825 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000826 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000827 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000828 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000829 return false;
830 }
831 case Match_MissingFeature:
832 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
833 return true;
834 case Match_InvalidOperand: {
835 SMLoc ErrorLoc = IDLoc;
836 if (ErrorInfo != ~0U) {
837 if (ErrorInfo >= Operands.size())
838 return Error(IDLoc, "too few operands for instruction");
839
Jack Carterd0bd6422013-04-18 00:41:53 +0000840 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
841 if (ErrorLoc == SMLoc())
842 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000843 }
844
845 return Error(ErrorLoc, "invalid operand for instruction");
846 }
847 case Match_MnemonicFail:
848 return Error(IDLoc, "invalid instruction");
849 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000850 return true;
851}
852
Jack Carter1ac53222013-02-20 23:11:17 +0000853int MipsAsmParser::matchCPURegisterName(StringRef Name) {
854 int CC;
855
856 if (Name == "at")
857 return getATReg();
858
859 CC = StringSwitch<unsigned>(Name)
860 .Case("zero", 0)
861 .Case("a0", 4)
862 .Case("a1", 5)
863 .Case("a2", 6)
864 .Case("a3", 7)
865 .Case("v0", 2)
866 .Case("v1", 3)
867 .Case("s0", 16)
868 .Case("s1", 17)
869 .Case("s2", 18)
870 .Case("s3", 19)
871 .Case("s4", 20)
872 .Case("s5", 21)
873 .Case("s6", 22)
874 .Case("s7", 23)
875 .Case("k0", 26)
876 .Case("k1", 27)
877 .Case("sp", 29)
878 .Case("fp", 30)
879 .Case("gp", 28)
880 .Case("ra", 31)
881 .Case("t0", 8)
882 .Case("t1", 9)
883 .Case("t2", 10)
884 .Case("t3", 11)
885 .Case("t4", 12)
886 .Case("t5", 13)
887 .Case("t6", 14)
888 .Case("t7", 15)
889 .Case("t8", 24)
890 .Case("t9", 25)
891 .Default(-1);
892
Jack Carterd0bd6422013-04-18 00:41:53 +0000893 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000894 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
895 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000896 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000897 CC += 4;
898
899 if (CC == -1 && isMips64())
900 CC = StringSwitch<unsigned>(Name)
901 .Case("a4", 8)
902 .Case("a5", 9)
903 .Case("a6", 10)
904 .Case("a7", 11)
905 .Case("kt0", 26)
906 .Case("kt1", 27)
907 .Case("s8", 30)
908 .Default(-1);
909
910 return CC;
911}
Jack Carterd0bd6422013-04-18 00:41:53 +0000912
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000913int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000914
Jack Cartera63b16a2012-09-07 00:23:42 +0000915 if (Name[0] == 'f') {
916 StringRef NumString = Name.substr(1);
917 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000918 if (NumString.getAsInteger(10, IntVal))
919 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000920 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +0000921 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000922 return IntVal;
923 }
924 return -1;
925}
Jack Cartera63b16a2012-09-07 00:23:42 +0000926
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000927int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
928
929 if (Name.startswith("fcc")) {
930 StringRef NumString = Name.substr(3);
931 unsigned IntVal;
932 if (NumString.getAsInteger(10, IntVal))
933 return -1; // This is not an integer.
934 if (IntVal > 7) // There are only 8 fcc registers.
935 return -1;
936 return IntVal;
937 }
938 return -1;
939}
940
941int MipsAsmParser::matchACRegisterName(StringRef Name) {
942
Akira Hatanaka274d24c2013-08-14 01:15:52 +0000943 if (Name.startswith("ac")) {
944 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000945 unsigned IntVal;
946 if (NumString.getAsInteger(10, IntVal))
947 return -1; // This is not an integer.
948 if (IntVal > 3) // There are only 3 acc registers.
949 return -1;
950 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +0000951 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000952 return -1;
953}
Jack Carterd0bd6422013-04-18 00:41:53 +0000954
Jack Carter5dc8ac92013-09-25 23:50:44 +0000955int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
956 unsigned IntVal;
957
958 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
959 return -1;
960
961 if (IntVal > 31)
962 return -1;
963
964 return IntVal;
965}
966
Vladimir Medic8cd17102013-06-20 11:21:49 +0000967int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
968
Vladimir Medic8cd17102013-06-20 11:21:49 +0000969 int CC;
970 CC = matchCPURegisterName(Name);
971 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000972 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
973 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000974 CC = matchFPURegisterName(Name);
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000975 //TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +0000976 if (CC != -1)
977 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
978 : Mips::FGR32RegClassID);
979 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000980}
981
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000982int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +0000983
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000984 switch (RegKind) {
985 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
986 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
987 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
988 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000989 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000990 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
991 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
992 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
993 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
994 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
Jack Carter5dc8ac92013-09-25 23:50:44 +0000995 case MipsOperand::Kind_MSA128BRegs: return Mips::MSA128BRegClassID;
996 case MipsOperand::Kind_MSA128HRegs: return Mips::MSA128HRegClassID;
997 case MipsOperand::Kind_MSA128WRegs: return Mips::MSA128WRegClassID;
998 case MipsOperand::Kind_MSA128DRegs: return Mips::MSA128DRegClassID;
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000999 default :return -1;
1000 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001001
Jack Cartera63b16a2012-09-07 00:23:42 +00001002}
Jack Carterb4dbc172012-09-05 23:34:03 +00001003
Jack Carter0b744b32012-10-04 02:29:46 +00001004bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1005 if (Reg > 31)
1006 return false;
1007
1008 aTReg = Reg;
1009 return true;
1010}
1011
Jack Carter1ac53222013-02-20 23:11:17 +00001012int MipsAsmParser::getATReg() {
1013 return Options.getATRegNum();
Jack Carter0b744b32012-10-04 02:29:46 +00001014}
1015
Jack Carterd0bd6422013-04-18 00:41:53 +00001016unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001017 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001018}
1019
Jack Carter873c7242013-01-12 01:03:14 +00001020int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001021 if (RegNum >
1022 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001023 return -1;
1024
Jack Carter873c7242013-01-12 01:03:14 +00001025 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001026}
1027
Jack Carter873c7242013-01-12 01:03:14 +00001028int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001029 const AsmToken &Tok = Parser.getTok();
1030 int RegNum = -1;
1031
1032 if (Tok.is(AsmToken::Identifier)) {
1033 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001034 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001035 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001036 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001037 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001038 return RegNum;
1039}
1040
Jack Carterd0bd6422013-04-18 00:41:53 +00001041bool MipsAsmParser::tryParseRegisterOperand(
1042 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001043
1044 SMLoc S = Parser.getTok().getLoc();
1045 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001046
Jack Carter873c7242013-01-12 01:03:14 +00001047 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001048 if (RegNo == -1)
1049 return true;
1050
Jack Carter873c7242013-01-12 01:03:14 +00001051 Operands.push_back(MipsOperand::CreateReg(RegNo, S,
Jack Carterd0bd6422013-04-18 00:41:53 +00001052 Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001053 Parser.Lex(); // Eat register token.
1054 return false;
1055}
1056
1057bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
1058 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001059 // Check if the current operand has a custom associated parser, if so, try to
1060 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001061 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1062 if (ResTy == MatchOperand_Success)
1063 return false;
1064 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1065 // there was a match, but an error occurred, in which case, just return that
1066 // the operand parsing failed.
1067 if (ResTy == MatchOperand_ParseFail)
1068 return true;
1069
1070 switch (getLexer().getKind()) {
1071 default:
1072 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1073 return true;
1074 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001075 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001076 SMLoc S = Parser.getTok().getLoc();
1077 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001078 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001079 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001080 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001081 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001082 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001083 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001084 if (getLexer().isNot(AsmToken::Dollar))
1085 return true;
1086
Jack Carterd0bd6422013-04-18 00:41:53 +00001087 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001088 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001089 return true;
1090
1091 if (!getLexer().is(AsmToken::RParen))
1092 return true;
1093
1094 S = Parser.getTok().getLoc();
1095 Operands.push_back(MipsOperand::CreateToken(")", S));
1096 Parser.Lex();
1097 }
1098 return false;
1099 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001100 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001101 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001102 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001103 return true;
1104
Jack Carter873c7242013-01-12 01:03:14 +00001105 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001106
Benjamin Kramerfa530572012-09-07 09:47:42 +00001107 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterb4dbc172012-09-05 23:34:03 +00001108
Jack Carterd0bd6422013-04-18 00:41:53 +00001109 // Otherwise create a symbol reference.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001110 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
Jack Carterb4dbc172012-09-05 23:34:03 +00001111 getContext());
1112
1113 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1114 return false;
1115 }
1116 case AsmToken::Identifier:
Jack Carterd76b2372013-03-21 21:44:16 +00001117 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001118 // we need to assigne the propper RegisterKind.
1119 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1120 return false;
1121 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001122 case AsmToken::LParen:
1123 case AsmToken::Minus:
1124 case AsmToken::Plus:
1125 case AsmToken::Integer:
1126 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001127 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001128 const MCExpr *IdVal;
1129 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001130 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001131 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001132 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001133 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1134 return false;
1135 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001136 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001137 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001138 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001139 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001140 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001141 return true;
1142
Jack Carter873c7242013-01-12 01:03:14 +00001143 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1144
Jack Carterdc1e35d2012-09-06 20:00:02 +00001145 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1146 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001147 } // case AsmToken::Percent
1148 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001149 return true;
1150}
1151
Jack Carterb5cf5902013-04-17 00:18:04 +00001152const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1153 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001154 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001155 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001156 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001157 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001158 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001159 short Val = MCE->getValue();
1160 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001161 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001162 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001163 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001164 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001165 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001166 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001167 if (LoSign)
1168 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001169 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001170 } else {
1171 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001172 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001173 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001174 }
1175
Jack Carterb5cf5902013-04-17 00:18:04 +00001176 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001177 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001178 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001179 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001180 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001181 return Res;
1182 }
1183
1184 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001185 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1186 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001187 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1188 return Res;
1189 }
1190
1191 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001192 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1193 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1194 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001195 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001196 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001197 return Expr;
1198}
1199
1200bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1201
1202 switch (Expr->getKind()) {
1203 case MCExpr::Constant:
1204 return true;
1205 case MCExpr::SymbolRef:
1206 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1207 case MCExpr::Binary:
1208 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1209 if (!isEvaluated(BE->getLHS()))
1210 return false;
1211 return isEvaluated(BE->getRHS());
1212 }
1213 case MCExpr::Unary:
1214 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1215 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001216 return false;
1217 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001218 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001219}
Jack Carterd0bd6422013-04-18 00:41:53 +00001220
Jack Carterb5cf5902013-04-17 00:18:04 +00001221bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001222 Parser.Lex(); // Eat the % token.
1223 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001224 if (Tok.isNot(AsmToken::Identifier))
1225 return true;
1226
1227 std::string Str = Tok.getIdentifier().str();
1228
Jack Carterd0bd6422013-04-18 00:41:53 +00001229 Parser.Lex(); // Eat the identifier.
1230 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001231 const MCExpr *IdVal;
1232 SMLoc EndLoc;
1233
1234 if (getLexer().getKind() == AsmToken::LParen) {
1235 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001236 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001237 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001238 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001239 const AsmToken &nextTok = Parser.getTok();
1240 if (nextTok.isNot(AsmToken::Identifier))
1241 return true;
1242 Str += "(%";
1243 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001244 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001245 if (getLexer().getKind() != AsmToken::LParen)
1246 return true;
1247 } else
1248 break;
1249 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001250 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001251 return true;
1252
1253 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001254 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001255
1256 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001257 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001258
Jack Carterd0bd6422013-04-18 00:41:53 +00001259 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001260 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001261}
1262
Jack Carterb4dbc172012-09-05 23:34:03 +00001263bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1264 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001265 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001266 RegNo = tryParseRegister(isMips64());
1267 EndLoc = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001268 return (RegNo == (unsigned) -1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001269}
1270
Jack Carterb5cf5902013-04-17 00:18:04 +00001271bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001272 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001273 bool Result = true;
1274
1275 while (getLexer().getKind() == AsmToken::LParen)
1276 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001277
Jack Carterd0bd6422013-04-18 00:41:53 +00001278 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001279 default:
1280 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001281 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001282 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001283 case AsmToken::Integer:
1284 case AsmToken::Minus:
1285 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001286 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001287 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001288 else
1289 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001290 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001291 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001292 break;
Jack Carter873c7242013-01-12 01:03:14 +00001293 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001294 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001295 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001296 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001297}
1298
Jack Carterb4dbc172012-09-05 23:34:03 +00001299MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Jack Carterd0bd6422013-04-18 00:41:53 +00001300 SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001301
1302 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001303 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001304 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001305 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001306 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001307 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001308
Jack Carterb5cf5902013-04-17 00:18:04 +00001309 if (getLexer().getKind() == AsmToken::LParen) {
1310 Parser.Lex();
1311 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001312 }
1313
Jack Carterb5cf5902013-04-17 00:18:04 +00001314 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001315 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001316 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001317
Jack Carterd0bd6422013-04-18 00:41:53 +00001318 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001319 if (Tok.isNot(AsmToken::LParen)) {
1320 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1321 if (Mnemonic->getToken() == "la") {
1322 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001323 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001324 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1325 return MatchOperand_Success;
1326 }
1327 if (Tok.is(AsmToken::EndOfStatement)) {
1328 SMLoc E = SMLoc::getFromPointer(
Jack Carterd0bd6422013-04-18 00:41:53 +00001329 Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001330
Jack Carterd0bd6422013-04-18 00:41:53 +00001331 // Zero register assumed, add a memory operand with ZERO as its base.
1332 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1333 : Mips::ZERO,
1334 IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001335 return MatchOperand_Success;
1336 }
1337 Error(Parser.getTok().getLoc(), "'(' expected");
1338 return MatchOperand_ParseFail;
1339 }
1340
Jack Carterd0bd6422013-04-18 00:41:53 +00001341 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001342 }
1343
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001344 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1345 (int) MipsOperand::Kind_GPR32);
1346 if (Res != MatchOperand_Success)
1347 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001348
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001349 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001350 Error(Parser.getTok().getLoc(), "')' expected");
1351 return MatchOperand_ParseFail;
1352 }
1353
Jack Carter873c7242013-01-12 01:03:14 +00001354 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1355
Jack Carterd0bd6422013-04-18 00:41:53 +00001356 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001357
1358 if (IdVal == 0)
1359 IdVal = MCConstantExpr::Create(0, getContext());
1360
Jack Carterd0bd6422013-04-18 00:41:53 +00001361 // Replace the register operand with the memory operand.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001362 MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1363 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001364 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001365 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001366 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001367 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1368 int64_t Imm;
1369 if (IdVal->EvaluateAsAbsolute(Imm))
1370 IdVal = MCConstantExpr::Create(Imm, getContext());
1371 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1372 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1373 getContext());
1374 }
1375
Jack Carterdc1e35d2012-09-06 20:00:02 +00001376 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1377 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001378 return MatchOperand_Success;
1379}
1380
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001381bool
1382MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1383 int RegKind) {
1384 // If the first token is not '$' we have an error.
1385 if (Parser.getTok().isNot(AsmToken::Dollar))
1386 return false;
1387
1388 SMLoc S = Parser.getTok().getLoc();
1389 Parser.Lex();
1390 AsmToken::TokenKind TkKind = getLexer().getKind();
1391 int Reg;
1392
1393 if (TkKind == AsmToken::Integer) {
1394 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1395 regKindToRegClass(RegKind));
1396 if (Reg == -1)
1397 return false;
1398 } else if (TkKind == AsmToken::Identifier) {
1399 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1400 return false;
1401 Reg = getReg(regKindToRegClass(RegKind), Reg);
1402 } else {
1403 return false;
1404 }
1405
1406 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1407 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1408 Operands.push_back(Op);
1409 Parser.Lex();
1410 return true;
1411}
1412
1413MipsAsmParser::OperandMatchResultTy
1414MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1415 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1416 MipsOperand::Kind_GPR32;
1417
1418 // Parse index register.
1419 if (!parsePtrReg(Operands, RegKind))
1420 return MatchOperand_NoMatch;
1421
1422 // Parse '('.
1423 if (Parser.getTok().isNot(AsmToken::LParen))
1424 return MatchOperand_NoMatch;
1425
1426 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1427 Parser.Lex();
1428
1429 // Parse base register.
1430 if (!parsePtrReg(Operands, RegKind))
1431 return MatchOperand_NoMatch;
1432
1433 // Parse ')'.
1434 if (Parser.getTok().isNot(AsmToken::RParen))
1435 return MatchOperand_NoMatch;
1436
1437 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1438 Parser.Lex();
1439
1440 return MatchOperand_Success;
1441}
1442
Jack Carter873c7242013-01-12 01:03:14 +00001443MipsAsmParser::OperandMatchResultTy
Vladimir Medic8cd17102013-06-20 11:21:49 +00001444MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1445 int RegKind) {
1446 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001447 if (getLexer().getKind() == AsmToken::Identifier
1448 && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001449 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001450 return MatchOperand_Success;
1451 return MatchOperand_NoMatch;
1452 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001453 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001454 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001455 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001456 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001457 if (!hasConsumedDollar) {
1458 Parser.Lex(); // Eat the '$'
1459 hasConsumedDollar = true;
1460 }
1461 if (getLexer().getKind() == AsmToken::Identifier) {
1462 int RegNum = -1;
1463 std::string RegName = Parser.getTok().getString().lower();
1464 // Match register by name
1465 switch (RegKind) {
1466 case MipsOperand::Kind_GPR32:
1467 case MipsOperand::Kind_GPR64:
1468 RegNum = matchCPURegisterName(RegName);
1469 break;
1470 case MipsOperand::Kind_AFGR64Regs:
1471 case MipsOperand::Kind_FGR64Regs:
1472 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001473 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001474 RegNum = matchFPURegisterName(RegName);
1475 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1476 RegNum /= 2;
Vladimir Medic65cd5742013-09-10 09:50:01 +00001477 else if (RegKind == MipsOperand::Kind_FGRH32Regs
1478 && !isFP64())
1479 if (RegNum != -1 && RegNum %2 != 0)
1480 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001481 break;
1482 case MipsOperand::Kind_FCCRegs:
1483 RegNum = matchFCCRegisterName(RegName);
1484 break;
1485 case MipsOperand::Kind_ACC64DSP:
1486 RegNum = matchACRegisterName(RegName);
1487 break;
1488 default: break; // No match, value is set to -1.
1489 }
1490 // No match found, return _NoMatch to give a chance to other round.
1491 if (RegNum < 0)
1492 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001493
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001494 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1495 if (RegVal == -1)
1496 return MatchOperand_NoMatch;
1497
1498 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1499 Parser.getTok().getLoc());
1500 Op->setRegKind(Kind);
1501 Operands.push_back(Op);
1502 hasConsumedDollar = false;
1503 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001504 return MatchOperand_Success;
1505 } else if (getLexer().getKind() == AsmToken::Integer) {
1506 unsigned RegNum = Parser.getTok().getIntVal();
1507 if (Kind == MipsOperand::Kind_HWRegs) {
1508 if (RegNum != 29)
1509 return MatchOperand_NoMatch;
1510 // Only hwreg 29 is supported, found at index 0.
1511 RegNum = 0;
1512 }
1513 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1514 if (Reg == -1)
1515 return MatchOperand_NoMatch;
1516 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1517 Op->setRegKind(Kind);
1518 Operands.push_back(Op);
1519 hasConsumedDollar = false;
1520 Parser.Lex(); // Eat the register number.
1521 if ((RegKind == MipsOperand::Kind_GPR32)
Vladimir Medic3467b902013-07-18 09:28:35 +00001522 && (getLexer().is(AsmToken::LParen))) {
1523 // Check if it is indexed addressing operand.
1524 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1525 Parser.Lex(); // Eat the parenthesis.
1526 if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1527 return MatchOperand_NoMatch;
1528 if (getLexer().isNot(AsmToken::RParen))
1529 return MatchOperand_NoMatch;
1530 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1531 Parser.Lex();
1532 }
Jack Carter873c7242013-01-12 01:03:14 +00001533 return MatchOperand_Success;
1534 }
1535 return MatchOperand_NoMatch;
1536}
Vladimir Medic64828a12013-07-16 10:07:14 +00001537
Vladimir Medic8cd17102013-06-20 11:21:49 +00001538MipsAsmParser::OperandMatchResultTy
Jack Carter5dc8ac92013-09-25 23:50:44 +00001539MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1540 int RegKind) {
1541 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1542 SMLoc S = Parser.getTok().getLoc();
1543 std::string RegName;
1544
1545 if (Parser.getTok().isNot(AsmToken::Dollar))
1546 return MatchOperand_NoMatch;
1547
1548 switch (RegKind) {
1549 default:
1550 return MatchOperand_ParseFail;
1551 case MipsOperand::Kind_MSA128BRegs:
1552 case MipsOperand::Kind_MSA128HRegs:
1553 case MipsOperand::Kind_MSA128WRegs:
1554 case MipsOperand::Kind_MSA128DRegs:
1555 break;
1556 }
1557
1558 Parser.Lex(); // Eat the '$'.
1559 if (getLexer().getKind() == AsmToken::Identifier)
1560 RegName = Parser.getTok().getString().lower();
1561 else
1562 return MatchOperand_ParseFail;
1563
1564 int RegNum = matchMSA128RegisterName(RegName);
1565
1566 if (RegNum < 0 || RegNum > 31)
1567 return MatchOperand_ParseFail;
1568
1569 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1570 if (RegVal == -1)
1571 return MatchOperand_ParseFail;
1572
1573 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1574 Parser.getTok().getLoc());
1575 Op->setRegKind(Kind);
1576 Operands.push_back(Op);
1577
1578 Parser.Lex(); // Eat the register identifier.
1579
1580 return MatchOperand_Success;
1581}
1582
1583MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001584MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001585
1586 if (!isMips64())
1587 return MatchOperand_NoMatch;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001588 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001589}
1590
1591MipsAsmParser::OperandMatchResultTy
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001592MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1593 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001594}
Jack Carter873c7242013-01-12 01:03:14 +00001595
Vladimir Medic233dd512013-06-24 10:05:34 +00001596MipsAsmParser::OperandMatchResultTy
1597MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1598
1599 if (isFP64())
1600 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001601 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1602}
1603
1604MipsAsmParser::OperandMatchResultTy
1605MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1606 if (!isFP64())
1607 return MatchOperand_NoMatch;
Vladimir Medic233dd512013-06-24 10:05:34 +00001608 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1609}
1610
1611MipsAsmParser::OperandMatchResultTy
1612MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001613 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1614}
1615
Vladimir Medic643b3982013-07-30 10:12:14 +00001616MipsAsmParser::OperandMatchResultTy
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001617MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1618 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1619}
1620
1621MipsAsmParser::OperandMatchResultTy
Vladimir Medic643b3982013-07-30 10:12:14 +00001622MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001623 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
Vladimir Medic643b3982013-07-30 10:12:14 +00001624}
1625
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001626MipsAsmParser::OperandMatchResultTy
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +00001627MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001628 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001629}
1630
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001631MipsAsmParser::OperandMatchResultTy
1632MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1633 // If the first token is not '$' we have an error.
1634 if (Parser.getTok().isNot(AsmToken::Dollar))
1635 return MatchOperand_NoMatch;
1636
1637 SMLoc S = Parser.getTok().getLoc();
1638 Parser.Lex(); // Eat the '$'
1639
1640 const AsmToken &Tok = Parser.getTok(); // Get next token.
1641
1642 if (Tok.isNot(AsmToken::Identifier))
1643 return MatchOperand_NoMatch;
1644
1645 if (!Tok.getIdentifier().startswith("ac"))
1646 return MatchOperand_NoMatch;
1647
1648 StringRef NumString = Tok.getIdentifier().substr(2);
1649
1650 unsigned IntVal;
1651 if (NumString.getAsInteger(10, IntVal))
1652 return MatchOperand_NoMatch;
1653
1654 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1655
1656 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1657 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1658 Operands.push_back(Op);
1659
1660 Parser.Lex(); // Eat the register number.
1661 return MatchOperand_Success;
1662}
1663
1664MipsAsmParser::OperandMatchResultTy
1665MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1666 // If the first token is not '$' we have an error.
1667 if (Parser.getTok().isNot(AsmToken::Dollar))
1668 return MatchOperand_NoMatch;
1669
1670 SMLoc S = Parser.getTok().getLoc();
1671 Parser.Lex(); // Eat the '$'
1672
1673 const AsmToken &Tok = Parser.getTok(); // Get next token.
1674
1675 if (Tok.isNot(AsmToken::Identifier))
1676 return MatchOperand_NoMatch;
1677
1678 if (!Tok.getIdentifier().startswith("ac"))
1679 return MatchOperand_NoMatch;
1680
1681 StringRef NumString = Tok.getIdentifier().substr(2);
1682
1683 unsigned IntVal;
1684 if (NumString.getAsInteger(10, IntVal))
1685 return MatchOperand_NoMatch;
1686
1687 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1688
1689 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1690 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1691 Operands.push_back(Op);
1692
1693 Parser.Lex(); // Eat the register number.
1694 return MatchOperand_Success;
1695}
1696
Vladimir Medic05bcde62013-09-16 10:29:42 +00001697MipsAsmParser::OperandMatchResultTy
1698MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1699 // If the first token is not '$' we have an error.
1700 if (Parser.getTok().isNot(AsmToken::Dollar))
1701 return MatchOperand_NoMatch;
1702
1703 SMLoc S = Parser.getTok().getLoc();
1704 Parser.Lex(); // Eat the '$'
1705
1706 const AsmToken &Tok = Parser.getTok(); // Get next token.
1707
1708 if (Tok.isNot(AsmToken::Integer))
1709 return MatchOperand_NoMatch;
1710
1711 unsigned IntVal = Tok.getIntVal();
1712
1713 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1714
1715 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1716 Op->setRegKind(MipsOperand::Kind_COP2);
1717 Operands.push_back(Op);
1718
1719 Parser.Lex(); // Eat the register number.
1720 return MatchOperand_Success;
1721}
1722
Jack Carter5dc8ac92013-09-25 23:50:44 +00001723MipsAsmParser::OperandMatchResultTy
1724MipsAsmParser::parseMSA128BRegs(
1725 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1726 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128BRegs);
1727}
1728
1729MipsAsmParser::OperandMatchResultTy
1730MipsAsmParser::parseMSA128HRegs(
1731 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1732 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128HRegs);
1733}
1734
1735MipsAsmParser::OperandMatchResultTy
1736MipsAsmParser::parseMSA128WRegs(
1737 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1738 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128WRegs);
1739}
1740
1741MipsAsmParser::OperandMatchResultTy
1742MipsAsmParser::parseMSA128DRegs(
1743 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1744 return parseMSARegs(Operands, (int) MipsOperand::Kind_MSA128DRegs);
1745}
1746
Jack Carterd0bd6422013-04-18 00:41:53 +00001747bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic8cd17102013-06-20 11:21:49 +00001748 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00001749
1750 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1751 if (Sym) {
1752 SMLoc S = Parser.getTok().getLoc();
1753 const MCExpr *Expr;
1754 if (Sym->isVariable())
1755 Expr = Sym->getVariableValue();
1756 else
1757 return false;
1758 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001759 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
Jack Carterd76b2372013-03-21 21:44:16 +00001760 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1761 const StringRef DefSymbol = Ref->getSymbol().getName();
1762 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00001763 int RegNum = -1;
1764 APInt IntVal(32, -1);
1765 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1766 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic64828a12013-07-16 10:07:14 +00001767 isMips64()
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001768 ? Mips::GPR64RegClassID
1769 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001770 else {
1771 // Lookup for the register with the corresponding name.
1772 switch (Kind) {
1773 case MipsOperand::Kind_AFGR64Regs:
1774 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001775 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001776 break;
1777 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001778 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001779 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001780 case MipsOperand::Kind_GPR64:
1781 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00001782 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001783 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00001784 break;
1785 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001786 if (RegNum > -1)
1787 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001788 }
Jack Carterd76b2372013-03-21 21:44:16 +00001789 if (RegNum > -1) {
1790 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001791 MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1792 Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00001793 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00001794 Operands.push_back(op);
1795 return true;
1796 }
1797 }
1798 } else if (Expr->getKind() == MCExpr::Constant) {
1799 Parser.Lex();
1800 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001801 MipsOperand *op = MipsOperand::CreateImm(Const, S,
Vladimir Medic64828a12013-07-16 10:07:14 +00001802 Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00001803 Operands.push_back(op);
1804 return true;
1805 }
1806 }
1807 return false;
1808}
Jack Carterd0bd6422013-04-18 00:41:53 +00001809
Jack Carter873c7242013-01-12 01:03:14 +00001810MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001811MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001812 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001813}
1814
1815MipsAsmParser::OperandMatchResultTy
Jack Carter873c7242013-01-12 01:03:14 +00001816MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001817 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00001818}
1819
Jack Carterdc1e35d2012-09-06 20:00:02 +00001820MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1821
1822 MCSymbolRefExpr::VariantKind VK
1823 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1824 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1825 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1826 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1827 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1828 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1829 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1830 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1831 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1832 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1833 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1834 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1835 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1836 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1837 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1838 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1839 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1840 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1841 .Default(MCSymbolRefExpr::VK_None);
1842
1843 return VK;
1844}
Jack Cartera63b16a2012-09-07 00:23:42 +00001845
Rafael Espindola870c4e92012-01-11 03:56:41 +00001846bool MipsAsmParser::
Chad Rosierf0e87202012-10-25 20:41:34 +00001847ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
Rafael Espindola870c4e92012-01-11 03:56:41 +00001848 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001849 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00001850 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00001851 Parser.eatToEndOfStatement();
1852 return Error(NameLoc, "Unknown instruction");
1853 }
Vladimir Medic64828a12013-07-16 10:07:14 +00001854 // First operand in MCInst is instruction mnemonic.
1855 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00001856
1857 // Read the remaining operands.
1858 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1859 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00001860 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001861 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001862 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001863 return Error(Loc, "unexpected token in argument list");
1864 }
1865
Jack Carterd0bd6422013-04-18 00:41:53 +00001866 while (getLexer().is(AsmToken::Comma)) {
1867 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00001868 // Parse and remember the operand.
1869 if (ParseOperand(Operands, Name)) {
1870 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001871 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001872 return Error(Loc, "unexpected token in argument list");
1873 }
1874 }
1875 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001876 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1877 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001878 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00001879 return Error(Loc, "unexpected token in argument list");
1880 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001881 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00001882 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00001883}
1884
Jack Carter0b744b32012-10-04 02:29:46 +00001885bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001886 SMLoc Loc = getLexer().getLoc();
1887 Parser.eatToEndOfStatement();
1888 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00001889}
1890
1891bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001892 // Line should look like: ".set noat".
1893 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00001894 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00001895 // eat noat
1896 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001897 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001898 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1899 reportParseError("unexpected token in statement");
1900 return false;
1901 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001902 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001903 return false;
1904}
Jack Carterd0bd6422013-04-18 00:41:53 +00001905
Jack Carter0b744b32012-10-04 02:29:46 +00001906bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001907 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00001908 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00001909 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00001910 getParser().Lex();
1911 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00001912 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00001913 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001914 return false;
1915 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001916 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00001917 if (getLexer().isNot(AsmToken::Dollar)) {
1918 reportParseError("unexpected token in statement");
1919 return false;
1920 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001921 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00001922 const AsmToken &Reg = Parser.getTok();
1923 if (Reg.is(AsmToken::Identifier)) {
1924 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1925 } else if (Reg.is(AsmToken::Integer)) {
1926 AtRegNo = Reg.getIntVal();
1927 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00001928 reportParseError("unexpected token in statement");
1929 return false;
1930 }
Jack Carter1ac53222013-02-20 23:11:17 +00001931
Jack Carterd0bd6422013-04-18 00:41:53 +00001932 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00001933 reportParseError("unexpected token in statement");
1934 return false;
1935 }
1936
1937 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00001938 reportParseError("unexpected token in statement");
1939 return false;
1940 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001941 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00001942
1943 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1944 reportParseError("unexpected token in statement");
1945 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001946 }
1947 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001948 return false;
1949 } else {
1950 reportParseError("unexpected token in statement");
1951 return false;
1952 }
1953}
1954
1955bool MipsAsmParser::parseSetReorderDirective() {
1956 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001957 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001958 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1959 reportParseError("unexpected token in statement");
1960 return false;
1961 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001962 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00001963 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001964 return false;
1965}
1966
1967bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00001968 Parser.Lex();
1969 // If this is not the end of the statement, report an error.
1970 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1971 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00001972 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00001973 }
1974 Options.setNoreorder();
1975 Parser.Lex(); // Consume the EndOfStatement.
1976 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001977}
1978
1979bool MipsAsmParser::parseSetMacroDirective() {
1980 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001981 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001982 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1983 reportParseError("unexpected token in statement");
1984 return false;
1985 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001986 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00001987 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00001988 return false;
1989}
1990
1991bool MipsAsmParser::parseSetNoMacroDirective() {
1992 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001993 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00001994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1995 reportParseError("`noreorder' must be set before `nomacro'");
1996 return false;
1997 }
Jack Carter99d2afe2012-10-05 23:55:28 +00001998 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00001999 reportParseError("`noreorder' must be set before `nomacro'");
2000 return false;
2001 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002002 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002003 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002004 return false;
2005}
Jack Carterd76b2372013-03-21 21:44:16 +00002006
2007bool MipsAsmParser::parseSetAssignment() {
2008 StringRef Name;
2009 const MCExpr *Value;
2010
2011 if (Parser.parseIdentifier(Name))
2012 reportParseError("expected identifier after .set");
2013
2014 if (getLexer().isNot(AsmToken::Comma))
2015 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002016 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002017
Jack Carter02593002013-05-28 22:21:05 +00002018 if (getLexer().is(AsmToken::Dollar)) {
2019 MCSymbol *Symbol;
2020 SMLoc DollarLoc = getLexer().getLoc();
2021 // Consume the dollar sign, and check for a following identifier.
2022 Parser.Lex();
2023 // We have a '$' followed by something, make sure they are adjacent.
2024 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2025 return true;
2026 StringRef Res = StringRef(DollarLoc.getPointer(),
2027 getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2028 Symbol = getContext().GetOrCreateSymbol(Res);
2029 Parser.Lex();
2030 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
2031 getContext());
2032 } else if (Parser.parseExpression(Value))
2033 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002034
Jack Carterd0bd6422013-04-18 00:41:53 +00002035 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002036 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002037 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002038 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002039 Sym = getContext().GetOrCreateSymbol(Name);
2040 Sym->setVariableValue(Value);
2041
2042 return false;
2043}
Jack Carterd0bd6422013-04-18 00:41:53 +00002044
Jack Carter0b744b32012-10-04 02:29:46 +00002045bool MipsAsmParser::parseDirectiveSet() {
2046
Jack Carterd0bd6422013-04-18 00:41:53 +00002047 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002048 const AsmToken &Tok = Parser.getTok();
2049
2050 if (Tok.getString() == "noat") {
2051 return parseSetNoAtDirective();
2052 } else if (Tok.getString() == "at") {
2053 return parseSetAtDirective();
2054 } else if (Tok.getString() == "reorder") {
2055 return parseSetReorderDirective();
2056 } else if (Tok.getString() == "noreorder") {
2057 return parseSetNoReorderDirective();
2058 } else if (Tok.getString() == "macro") {
2059 return parseSetMacroDirective();
2060 } else if (Tok.getString() == "nomacro") {
2061 return parseSetNoMacroDirective();
2062 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002063 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002064 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002065 return false;
2066 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002067 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002068 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002069 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002070 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002071 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002072 parseSetAssignment();
2073 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002074 }
Jack Carter07c818d2013-01-25 01:31:34 +00002075
Jack Carter0b744b32012-10-04 02:29:46 +00002076 return true;
2077}
2078
Jack Carter07c818d2013-01-25 01:31:34 +00002079/// parseDirectiveWord
2080/// ::= .word [ expression (, expression)* ]
2081bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2082 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2083 for (;;) {
2084 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002085 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002086 return true;
2087
2088 getParser().getStreamer().EmitValue(Value, Size);
2089
2090 if (getLexer().is(AsmToken::EndOfStatement))
2091 break;
2092
2093 // FIXME: Improve diagnostic.
2094 if (getLexer().isNot(AsmToken::Comma))
2095 return Error(L, "unexpected token in directive");
2096 Parser.Lex();
2097 }
2098 }
2099
2100 Parser.Lex();
2101 return false;
2102}
2103
Jack Carter0b744b32012-10-04 02:29:46 +00002104bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00002105
Jack Carter07c818d2013-01-25 01:31:34 +00002106 StringRef IDVal = DirectiveID.getString();
2107
Jack Carterd0bd6422013-04-18 00:41:53 +00002108 if (IDVal == ".ent") {
2109 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002110 Parser.Lex();
2111 return false;
2112 }
2113
Jack Carter07c818d2013-01-25 01:31:34 +00002114 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002115 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002116 Parser.Lex();
2117 return false;
2118 }
2119
Jack Carter07c818d2013-01-25 01:31:34 +00002120 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002121 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002122 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002123 return false;
2124 }
2125
Jack Carter07c818d2013-01-25 01:31:34 +00002126 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002127 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002128 }
2129
Jack Carter07c818d2013-01-25 01:31:34 +00002130 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002131 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002132 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002133 return false;
2134 }
2135
Jack Carter07c818d2013-01-25 01:31:34 +00002136 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002137 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002138 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002139 return false;
2140 }
2141
Jack Carter07c818d2013-01-25 01:31:34 +00002142 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002143 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002144 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002145 return false;
2146 }
2147
Jack Carter07c818d2013-01-25 01:31:34 +00002148 if (IDVal == ".word") {
2149 parseDirectiveWord(4, DirectiveID.getLoc());
2150 return false;
2151 }
2152
Rafael Espindola870c4e92012-01-11 03:56:41 +00002153 return true;
2154}
2155
Rafael Espindola870c4e92012-01-11 03:56:41 +00002156extern "C" void LLVMInitializeMipsAsmParser() {
2157 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2158 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2159 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2160 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2161}
Jack Carterb4dbc172012-09-05 23:34:03 +00002162
2163#define GET_REGISTER_MATCHER
2164#define GET_MATCHER_IMPLEMENTATION
2165#include "MipsGenAsmMatcher.inc"