blob: cae3999c12bc94bce5f53c26b83cc840fe8145e5 [file] [log] [blame]
Jia Liu9f610112012-02-17 08:55:11 +00001//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
Rafael Espindola870c4e92012-01-11 03:56:41 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/MipsMCTargetDesc.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000011#include "MipsRegisterInfo.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000012#include "MipsTargetStreamer.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000013#include "llvm/ADT/StringSwitch.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/MC/MCParser/MCAsmLexer.h"
18#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000019#include "llvm/MC/MCStreamer.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000022#include "llvm/MC/MCTargetAsmParser.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000023#include "llvm/Support/TargetRegistry.h"
Jack Carter02593002013-05-28 22:21:05 +000024#include "llvm/ADT/APInt.h"
Matheus Almeidae0d75aa2013-12-13 11:11:02 +000025#include "llvm/Support/MathExtras.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000026
27using namespace llvm;
28
Joey Gouly0e76fa72013-09-12 10:28:05 +000029namespace llvm {
30class MCInstrInfo;
31}
32
Rafael Espindola870c4e92012-01-11 03:56:41 +000033namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000034class MipsAssemblerOptions {
35public:
Vladimir Medic4c299852013-11-06 11:27:05 +000036 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
Jack Carterb4dbc172012-09-05 23:34:03 +000037
Vladimir Medic4c299852013-11-06 11:27:05 +000038 unsigned getATRegNum() { return aTReg; }
Jack Carter0b744b32012-10-04 02:29:46 +000039 bool setATReg(unsigned Reg);
40
Vladimir Medic4c299852013-11-06 11:27:05 +000041 bool isReorder() { return reorder; }
42 void setReorder() { reorder = true; }
43 void setNoreorder() { reorder = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000044
Vladimir Medic4c299852013-11-06 11:27:05 +000045 bool isMacro() { return macro; }
46 void setMacro() { macro = true; }
47 void setNomacro() { macro = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000048
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
Rafael Espindolaa17151a2013-10-08 13:08:17 +000059 MipsTargetStreamer &getTargetStreamer() {
60 MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer();
61 return static_cast<MipsTargetStreamer &>(TS);
62 }
63
Jack Carterb4dbc172012-09-05 23:34:03 +000064 MCSubtargetInfo &STI;
65 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000066 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000067 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000068
Akira Hatanaka7605630c2012-08-17 20:16:42 +000069#define GET_ASSEMBLER_HEADER
70#include "MipsGenAsmMatcher.inc"
71
Chad Rosier49963552012-10-13 00:26:04 +000072 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Vladimir Medic4c299852013-11-06 11:27:05 +000073 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000074 MCStreamer &Out, unsigned &ErrorInfo,
75 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000076
77 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
78
Chad Rosierf0e87202012-10-25 20:41:34 +000079 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
80 SMLoc NameLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +000081 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000082
83 bool ParseDirective(AsmToken DirectiveID);
84
Jack Carterb4dbc172012-09-05 23:34:03 +000085 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000086 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000087
88 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000089 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Jack Carter5dc8ac92013-09-25 23:50:44 +000090
91 MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +000092 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
93 int RegKind);
94
95 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000096 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000097
Vladimir Medic4c299852013-11-06 11:27:05 +000098 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
99 int RegKind);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000100
101 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000102 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000103
Jack Carter873c7242013-01-12 01:03:14 +0000104 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000105 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000106
107 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000108 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000109
110 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000111 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000112
113 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000114 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000115
Vladimir Medic233dd512013-06-24 10:05:34 +0000116 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000117 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000118
119 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000120 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000121
122 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000123 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000124
Vladimir Medic643b3982013-07-30 10:12:14 +0000125 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000126 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000127
128 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000129 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic643b3982013-07-30 10:12:14 +0000130
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000131 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000132 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000133
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000134 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000135 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000136
137 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000138 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000139
Vladimir Medic05bcde62013-09-16 10:29:42 +0000140 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000141 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic05bcde62013-09-16 10:29:42 +0000142
Jack Carter5dc8ac92013-09-25 23:50:44 +0000143 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000144 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000145
146 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000147 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000148
149 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000150 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000151
152 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000153 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000154
Vladimir Medic2b953d02013-10-01 09:48:56 +0000155 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000156 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000157
158 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000159 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic2b953d02013-10-01 09:48:56 +0000160
Matheus Almeida779c5932013-11-18 12:32:49 +0000161 MipsAsmParser::OperandMatchResultTy
162 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
163
164 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000165 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000166
Vladimir Medic4c299852013-11-06 11:27:05 +0000167 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
Jack Carterb4dbc172012-09-05 23:34:03 +0000168 StringRef Mnemonic);
169
Jack Carter873c7242013-01-12 01:03:14 +0000170 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000171
Vladimir Medic4c299852013-11-06 11:27:05 +0000172 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000173 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000174
Jack Carter30a59822012-10-04 04:03:53 +0000175 bool needsExpansion(MCInst &Inst);
176
177 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000178 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000179 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000180 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000181 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
183 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000185 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000186 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
187 bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000188 bool reportParseError(StringRef ErrorMsg);
189
Jack Carterb5cf5902013-04-17 00:18:04 +0000190 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000191 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000192
Vladimir Medic4c299852013-11-06 11:27:05 +0000193 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000194
195 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000196 bool parseDirectiveSet();
Jack Carter6ef6cc52013-11-19 20:53:28 +0000197 bool parseDirectiveMipsHackStocg();
198 bool parseDirectiveMipsHackELFFlags();
Jack Carter0b744b32012-10-04 02:29:46 +0000199
200 bool parseSetAtDirective();
201 bool parseSetNoAtDirective();
202 bool parseSetMacroDirective();
203 bool parseSetNoMacroDirective();
204 bool parseSetReorderDirective();
205 bool parseSetNoReorderDirective();
206
Jack Carterd76b2372013-03-21 21:44:16 +0000207 bool parseSetAssignment();
208
Jack Carter07c818d2013-01-25 01:31:34 +0000209 bool parseDirectiveWord(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000210 bool parseDirectiveGpWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000211
Jack Carterdc1e35d2012-09-06 20:00:02 +0000212 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000213
Jack Carterb4dbc172012-09-05 23:34:03 +0000214 bool isMips64() const {
215 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
216 }
217
Jack Cartera63b16a2012-09-07 00:23:42 +0000218 bool isFP64() const {
219 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
220 }
221
Vladimir Medic4c299852013-11-06 11:27:05 +0000222 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000223
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000224 bool isMicroMips() const {
225 return STI.getFeatureBits() & Mips::FeatureMicroMips;
226 }
227
Jack Carter873c7242013-01-12 01:03:14 +0000228 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000229
Jack Carter1ac53222013-02-20 23:11:17 +0000230 int matchCPURegisterName(StringRef Symbol);
231
Jack Carter873c7242013-01-12 01:03:14 +0000232 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000233
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000234 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000235
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000236 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000237
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000238 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000239
Jack Carter5dc8ac92013-09-25 23:50:44 +0000240 int matchMSA128RegisterName(StringRef Name);
241
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000242 int matchMSA128CtrlRegisterName(StringRef Name);
243
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000244 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000245
Jack Carterd0bd6422013-04-18 00:41:53 +0000246 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000247
Jack Carter1ac53222013-02-20 23:11:17 +0000248 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000249
250 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000251 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000252
253 // Helper function that checks if the value of a vector index is within the
254 // boundaries of accepted values for each RegisterKind
255 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
256 bool validateMSAIndex(int Val, int RegKind);
257
Rafael Espindola870c4e92012-01-11 03:56:41 +0000258public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000259 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
260 const MCInstrInfo &MII)
261 : MCTargetAsmParser(), STI(sti), Parser(parser),
262 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000263 // Initialize the set of available features.
264 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000265 }
266
Jack Carterb4dbc172012-09-05 23:34:03 +0000267 MCAsmParser &getParser() const { return Parser; }
268 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000269};
270}
271
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000272namespace {
273
274/// MipsOperand - Instances of this class represent a parsed Mips machine
275/// instruction.
276class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000277
Jack Carter873c7242013-01-12 01:03:14 +0000278public:
279 enum RegisterKind {
280 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000281 Kind_GPR32,
282 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000283 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000284 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000285 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000286 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000287 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000288 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000289 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000290 Kind_ACC64DSP,
291 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000292 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000293 Kind_COP2,
294 Kind_MSA128BRegs,
295 Kind_MSA128HRegs,
296 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000297 Kind_MSA128DRegs,
298 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000299 };
300
301private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000302 enum KindTy {
303 k_CondCode,
304 k_CoprocNum,
305 k_Immediate,
306 k_Memory,
307 k_PostIndexRegister,
308 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000309 k_PtrReg,
Matheus Almeida779c5932013-11-18 12:32:49 +0000310 k_Token,
311 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000312 } Kind;
313
314 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000315
Eric Christopher8996c5d2013-03-15 00:42:55 +0000316 struct Token {
317 const char *Data;
318 unsigned Length;
319 };
320
321 struct RegOp {
322 unsigned RegNum;
323 RegisterKind Kind;
324 };
325
326 struct ImmOp {
327 const MCExpr *Val;
328 };
329
330 struct MemOp {
331 unsigned Base;
332 const MCExpr *Off;
333 };
334
Jack Carterb4dbc172012-09-05 23:34:03 +0000335 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000336 struct Token Tok;
337 struct RegOp Reg;
338 struct ImmOp Imm;
339 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000340 };
341
342 SMLoc StartLoc, EndLoc;
343
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000344public:
345 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000346 assert(N == 1 && "Invalid number of operands!");
347 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000348 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000349
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000350 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
351 assert(N == 1 && "Invalid number of operands!");
352 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
353 }
354
Vladimir Medic4c299852013-11-06 11:27:05 +0000355 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000356 // Add as immediate when possible. Null MCExpr = 0.
357 if (Expr == 0)
358 Inst.addOperand(MCOperand::CreateImm(0));
359 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
360 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
361 else
362 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000363 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000364
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000365 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000366 assert(N == 1 && "Invalid number of operands!");
367 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000368 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000369 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000370
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000371 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000372 assert(N == 2 && "Invalid number of operands!");
373
374 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
375
376 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000377 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000378 }
379
380 bool isReg() const { return Kind == k_Register; }
381 bool isImm() const { return Kind == k_Immediate; }
382 bool isToken() const { return Kind == k_Token; }
383 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000384 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000385 bool isInvNum() const { return Kind == k_Immediate; }
Matheus Almeida779c5932013-11-18 12:32:49 +0000386 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000387
388 StringRef getToken() const {
389 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000390 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000391 }
392
393 unsigned getReg() const {
394 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000395 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000396 }
397
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000398 unsigned getPtrReg() const {
399 assert((Kind == k_PtrReg) && "Invalid access!");
400 return Reg.RegNum;
401 }
402
Jack Carter873c7242013-01-12 01:03:14 +0000403 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000404 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000405 Reg.Kind = RegKind;
406 }
407
Jack Carterb4dbc172012-09-05 23:34:03 +0000408 const MCExpr *getImm() const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000409 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000410 return Imm.Val;
411 }
412
Jack Carterdc1e35d2012-09-06 20:00:02 +0000413 unsigned getMemBase() const {
414 assert((Kind == k_Memory) && "Invalid access!");
415 return Mem.Base;
416 }
417
418 const MCExpr *getMemOff() const {
419 assert((Kind == k_Memory) && "Invalid access!");
420 return Mem.Off;
421 }
422
Jack Carterb4dbc172012-09-05 23:34:03 +0000423 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
424 MipsOperand *Op = new MipsOperand(k_Token);
425 Op->Tok.Data = Str.data();
426 Op->Tok.Length = Str.size();
427 Op->StartLoc = S;
428 Op->EndLoc = S;
429 return Op;
430 }
431
432 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
433 MipsOperand *Op = new MipsOperand(k_Register);
434 Op->Reg.RegNum = RegNum;
435 Op->StartLoc = S;
436 Op->EndLoc = E;
437 return Op;
438 }
439
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000440 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
441 MipsOperand *Op = new MipsOperand(k_PtrReg);
442 Op->Reg.RegNum = RegNum;
443 Op->StartLoc = S;
444 Op->EndLoc = E;
445 return Op;
446 }
447
Jack Carterb4dbc172012-09-05 23:34:03 +0000448 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
449 MipsOperand *Op = new MipsOperand(k_Immediate);
450 Op->Imm.Val = Val;
451 Op->StartLoc = S;
452 Op->EndLoc = E;
453 return Op;
454 }
455
Matheus Almeida779c5932013-11-18 12:32:49 +0000456 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
457 MipsOperand *Op = new MipsOperand(k_LSAImm);
458 Op->Imm.Val = Val;
459 Op->StartLoc = S;
460 Op->EndLoc = E;
461 return Op;
462 }
463
464 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
465 SMLoc S, SMLoc E) {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000466 MipsOperand *Op = new MipsOperand(k_Memory);
467 Op->Mem.Base = Base;
468 Op->Mem.Off = Off;
469 Op->StartLoc = S;
470 Op->EndLoc = E;
471 return Op;
472 }
473
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000474 bool isGPR32Asm() const {
475 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000476 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000477 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000478 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
479 }
480
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000481 bool isGPR64Asm() const {
482 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000483 }
Jack Carter873c7242013-01-12 01:03:14 +0000484
485 bool isHWRegsAsm() const {
486 assert((Kind == k_Register) && "Invalid access!");
487 return Reg.Kind == Kind_HWRegs;
488 }
Jack Carter873c7242013-01-12 01:03:14 +0000489
Jack Carter873c7242013-01-12 01:03:14 +0000490 bool isCCRAsm() const {
491 assert((Kind == k_Register) && "Invalid access!");
492 return Reg.Kind == Kind_CCRRegs;
493 }
494
Vladimir Medic4c299852013-11-06 11:27:05 +0000495 bool isAFGR64Asm() const {
Vladimir Medic233dd512013-06-24 10:05:34 +0000496 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
497 }
498
499 bool isFGR64Asm() const {
500 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
501 }
502
503 bool isFGR32Asm() const {
504 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
505 }
506
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000507 bool isFGRH32Asm() const {
508 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
509 }
510
Vladimir Medic643b3982013-07-30 10:12:14 +0000511 bool isFCCRegsAsm() const {
512 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
513 }
514
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000515 bool isACC64DSPAsm() const {
516 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000517 }
518
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000519 bool isLO32DSPAsm() const {
520 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
521 }
522
523 bool isHI32DSPAsm() const {
524 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
525 }
526
Vladimir Medic4c299852013-11-06 11:27:05 +0000527 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
Vladimir Medic05bcde62013-09-16 10:29:42 +0000528
Jack Carter5dc8ac92013-09-25 23:50:44 +0000529 bool isMSA128BAsm() const {
530 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
531 }
532
533 bool isMSA128HAsm() const {
534 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
535 }
536
537 bool isMSA128WAsm() const {
538 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
539 }
540
541 bool isMSA128DAsm() const {
542 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
543 }
544
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000545 bool isMSA128CRAsm() const {
546 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
547 }
548
Jack Carterb4dbc172012-09-05 23:34:03 +0000549 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000550 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000551 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000552 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000553
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000554 virtual void print(raw_ostream &OS) const {
555 llvm_unreachable("unimplemented!");
556 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000557}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000558} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000559
Jack Carter9e65aa32013-03-22 00:05:30 +0000560namespace llvm {
561extern const MCInstrDesc MipsInsts[];
562}
563static const MCInstrDesc &getInstDesc(unsigned Opcode) {
564 return MipsInsts[Opcode];
565}
566
567bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000568 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000569 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
570 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000571
572 if (MCID.isBranch() || MCID.isCall()) {
573 const unsigned Opcode = Inst.getOpcode();
574 MCOperand Offset;
575
576 switch (Opcode) {
577 default:
578 break;
579 case Mips::BEQ:
580 case Mips::BNE:
581 assert (MCID.getNumOperands() == 3 && "unexpected number of operands");
582 Offset = Inst.getOperand(2);
583 if (!Offset.isImm())
584 break; // We'll deal with this situation later on when applying fixups.
585 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
586 return Error(IDLoc, "branch target out of range");
587 if (OffsetToAlignment (Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
588 return Error(IDLoc, "branch to misaligned address");
589 break;
590 case Mips::BGEZ:
591 case Mips::BGTZ:
592 case Mips::BLEZ:
593 case Mips::BLTZ:
594 case Mips::BGEZAL:
595 case Mips::BLTZAL:
596 case Mips::BC1F:
597 case Mips::BC1T:
598 assert (MCID.getNumOperands() == 2 && "unexpected number of operands");
599 Offset = Inst.getOperand(1);
600 if (!Offset.isImm())
601 break; // We'll deal with this situation later on when applying fixups.
602 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
603 return Error(IDLoc, "branch target out of range");
604 if (OffsetToAlignment (Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
605 return Error(IDLoc, "branch to misaligned address");
606 break;
607 }
608 }
609
Jack Carterc15c1d22013-04-25 23:31:35 +0000610 if (MCID.hasDelaySlot() && Options.isReorder()) {
611 // If this instruction has a delay slot and .set reorder is active,
612 // emit a NOP after it.
613 Instructions.push_back(Inst);
614 MCInst NopInst;
615 NopInst.setOpcode(Mips::SLL);
616 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
617 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
618 NopInst.addOperand(MCOperand::CreateImm(0));
619 Instructions.push_back(NopInst);
620 return false;
621 }
622
Jack Carter9e65aa32013-03-22 00:05:30 +0000623 if (MCID.mayLoad() || MCID.mayStore()) {
624 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000625 // reference or immediate we may have to expand instructions.
626 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000627 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000628 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
629 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000630 MCOperand &Op = Inst.getOperand(i);
631 if (Op.isImm()) {
632 int MemOffset = Op.getImm();
633 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000634 // Offset can't exceed 16bit value.
635 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000636 return false;
637 }
638 } else if (Op.isExpr()) {
639 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000640 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000641 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000642 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000643 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000644 // Expand symbol.
645 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000646 return false;
647 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000648 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000649 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000650 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000651 }
652 }
653 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000654 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000655 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000656
657 if (needsExpansion(Inst))
658 expandInstruction(Inst, IDLoc, Instructions);
659 else
660 Instructions.push_back(Inst);
661
662 return false;
663}
664
Jack Carter30a59822012-10-04 04:03:53 +0000665bool MipsAsmParser::needsExpansion(MCInst &Inst) {
666
Jack Carterd0bd6422013-04-18 00:41:53 +0000667 switch (Inst.getOpcode()) {
668 case Mips::LoadImm32Reg:
669 case Mips::LoadAddr32Imm:
670 case Mips::LoadAddr32Reg:
671 return true;
672 default:
673 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000674 }
675}
Jack Carter92995f12012-10-06 00:53:28 +0000676
Jack Carter30a59822012-10-04 04:03:53 +0000677void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000678 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000679 switch (Inst.getOpcode()) {
680 case Mips::LoadImm32Reg:
681 return expandLoadImm(Inst, IDLoc, Instructions);
682 case Mips::LoadAddr32Imm:
683 return expandLoadAddressImm(Inst, IDLoc, Instructions);
684 case Mips::LoadAddr32Reg:
685 return expandLoadAddressReg(Inst, IDLoc, Instructions);
686 }
Jack Carter30a59822012-10-04 04:03:53 +0000687}
Jack Carter92995f12012-10-06 00:53:28 +0000688
Jack Carter30a59822012-10-04 04:03:53 +0000689void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000690 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000691 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000692 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000693 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000694 const MCOperand &RegOp = Inst.getOperand(0);
695 assert(RegOp.isReg() && "expected register operand kind");
696
697 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000698 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000699 if (0 <= ImmValue && ImmValue <= 65535) {
700 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000701 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000702 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000703 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000704 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000705 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000706 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000707 } else if (ImmValue < 0 && ImmValue >= -32768) {
708 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000709 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000710 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000711 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000712 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000713 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000714 Instructions.push_back(tmpInst);
715 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000716 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000717 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000718 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000719 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000720 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
721 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000722 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000723 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000724 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000725 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
726 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
727 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
728 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000729 Instructions.push_back(tmpInst);
730 }
731}
Jack Carter92995f12012-10-06 00:53:28 +0000732
Vladimir Medic4c299852013-11-06 11:27:05 +0000733void
734MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
735 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000736 MCInst tmpInst;
737 const MCOperand &ImmOp = Inst.getOperand(2);
738 assert(ImmOp.isImm() && "expected immediate operand kind");
739 const MCOperand &SrcRegOp = Inst.getOperand(1);
740 assert(SrcRegOp.isReg() && "expected register operand kind");
741 const MCOperand &DstRegOp = Inst.getOperand(0);
742 assert(DstRegOp.isReg() && "expected register operand kind");
743 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000744 if (-32768 <= ImmValue && ImmValue <= 65535) {
745 // For -32768 <= j <= 65535.
746 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000747 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000748 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
749 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
750 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
751 Instructions.push_back(tmpInst);
752 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000753 // For any other value of j that is representable as a 32-bit integer.
754 // la d,j(s) => lui d,hi16(j)
755 // ori d,d,lo16(j)
756 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000757 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000758 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
759 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
760 Instructions.push_back(tmpInst);
761 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000762 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000763 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
764 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
765 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
766 Instructions.push_back(tmpInst);
767 tmpInst.clear();
768 tmpInst.setOpcode(Mips::ADDu);
769 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
770 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
771 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
772 Instructions.push_back(tmpInst);
773 }
774}
775
Vladimir Medic4c299852013-11-06 11:27:05 +0000776void
777MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
778 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000779 MCInst tmpInst;
780 const MCOperand &ImmOp = Inst.getOperand(1);
781 assert(ImmOp.isImm() && "expected immediate operand kind");
782 const MCOperand &RegOp = Inst.getOperand(0);
783 assert(RegOp.isReg() && "expected register operand kind");
784 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000785 if (-32768 <= ImmValue && ImmValue <= 65535) {
786 // For -32768 <= j <= 65535.
787 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000788 tmpInst.setOpcode(Mips::ADDiu);
789 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000790 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000791 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
792 Instructions.push_back(tmpInst);
793 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000794 // For any other value of j that is representable as a 32-bit integer.
795 // la d,j => lui d,hi16(j)
796 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000797 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000798 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
799 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
800 Instructions.push_back(tmpInst);
801 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000802 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000803 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
804 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
805 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
806 Instructions.push_back(tmpInst);
807 }
808}
809
Jack Carter9e65aa32013-03-22 00:05:30 +0000810void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000811 SmallVectorImpl<MCInst> &Instructions,
812 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000813 const MCSymbolRefExpr *SR;
814 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000815 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000816 const MCExpr *ExprOffset;
817 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000818 unsigned AtRegNum = getReg(
819 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000820 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000821 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
822 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000823 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000824 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
825 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000826 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000827 if (isImmOpnd) {
828 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
829 ImmOffset = Inst.getOperand(2).getImm();
830 LoOffset = ImmOffset & 0x0000ffff;
831 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000832 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000833 if (LoOffset & 0x8000)
834 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000835 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000836 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000837 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000838 TempInst.setLoc(IDLoc);
839 // 1st instruction in expansion is LUi. For load instruction we can use
840 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000841 // but for stores we must use $at.
842 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000843 TempInst.setOpcode(Mips::LUi);
844 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
845 if (isImmOpnd)
846 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
847 else {
848 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000849 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000850 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
851 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
852 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000853 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000854 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000855 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000856 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000857 }
858 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000859 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000860 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000861 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000862 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000863 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000864 TempInst.setOpcode(Mips::ADDu);
865 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
866 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
867 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
868 Instructions.push_back(TempInst);
869 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000870 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000871 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000872 TempInst.setOpcode(Inst.getOpcode());
873 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
874 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
875 if (isImmOpnd)
876 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
877 else {
878 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000879 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
880 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
881 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000882 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000883 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000884 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000885 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000886 }
887 }
888 Instructions.push_back(TempInst);
889 TempInst.clear();
890}
891
Vladimir Medic4c299852013-11-06 11:27:05 +0000892bool MipsAsmParser::MatchAndEmitInstruction(
893 SMLoc IDLoc, unsigned &Opcode,
894 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
895 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000896 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000897 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000898 unsigned MatchResult =
899 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000900
901 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000902 default:
903 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000904 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000905 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000906 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000908 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000909 return false;
910 }
911 case Match_MissingFeature:
912 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
913 return true;
914 case Match_InvalidOperand: {
915 SMLoc ErrorLoc = IDLoc;
916 if (ErrorInfo != ~0U) {
917 if (ErrorInfo >= Operands.size())
918 return Error(IDLoc, "too few operands for instruction");
919
Vladimir Medic4c299852013-11-06 11:27:05 +0000920 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000921 if (ErrorLoc == SMLoc())
922 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000923 }
924
925 return Error(ErrorLoc, "invalid operand for instruction");
926 }
927 case Match_MnemonicFail:
928 return Error(IDLoc, "invalid instruction");
929 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000930 return true;
931}
932
Jack Carter1ac53222013-02-20 23:11:17 +0000933int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000934 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +0000935
936 if (Name == "at")
937 return getATReg();
938
Vladimir Medic4c299852013-11-06 11:27:05 +0000939 CC = StringSwitch<unsigned>(Name)
940 .Case("zero", 0)
941 .Case("a0", 4)
942 .Case("a1", 5)
943 .Case("a2", 6)
944 .Case("a3", 7)
945 .Case("v0", 2)
946 .Case("v1", 3)
947 .Case("s0", 16)
948 .Case("s1", 17)
949 .Case("s2", 18)
950 .Case("s3", 19)
951 .Case("s4", 20)
952 .Case("s5", 21)
953 .Case("s6", 22)
954 .Case("s7", 23)
955 .Case("k0", 26)
956 .Case("k1", 27)
957 .Case("sp", 29)
958 .Case("fp", 30)
959 .Case("gp", 28)
960 .Case("ra", 31)
961 .Case("t0", 8)
962 .Case("t1", 9)
963 .Case("t2", 10)
964 .Case("t3", 11)
965 .Case("t4", 12)
966 .Case("t5", 13)
967 .Case("t6", 14)
968 .Case("t7", 15)
969 .Case("t8", 24)
970 .Case("t9", 25)
971 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000972
Jack Carterd0bd6422013-04-18 00:41:53 +0000973 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000974 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
975 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000976 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000977 CC += 4;
978
979 if (CC == -1 && isMips64())
980 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +0000981 .Case("a4", 8)
982 .Case("a5", 9)
983 .Case("a6", 10)
984 .Case("a7", 11)
985 .Case("kt0", 26)
986 .Case("kt1", 27)
987 .Case("s8", 30)
988 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000989
990 return CC;
991}
Jack Carterd0bd6422013-04-18 00:41:53 +0000992
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000993int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000994
Jack Cartera63b16a2012-09-07 00:23:42 +0000995 if (Name[0] == 'f') {
996 StringRef NumString = Name.substr(1);
997 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +0000998 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +0000999 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001000 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001001 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001002 return IntVal;
1003 }
1004 return -1;
1005}
Jack Cartera63b16a2012-09-07 00:23:42 +00001006
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001007int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1008
1009 if (Name.startswith("fcc")) {
1010 StringRef NumString = Name.substr(3);
1011 unsigned IntVal;
1012 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001013 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001014 if (IntVal > 7) // There are only 8 fcc registers.
1015 return -1;
1016 return IntVal;
1017 }
1018 return -1;
1019}
1020
1021int MipsAsmParser::matchACRegisterName(StringRef Name) {
1022
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001023 if (Name.startswith("ac")) {
1024 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001025 unsigned IntVal;
1026 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001027 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001028 if (IntVal > 3) // There are only 3 acc registers.
1029 return -1;
1030 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001031 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001032 return -1;
1033}
Jack Carterd0bd6422013-04-18 00:41:53 +00001034
Jack Carter5dc8ac92013-09-25 23:50:44 +00001035int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1036 unsigned IntVal;
1037
1038 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1039 return -1;
1040
1041 if (IntVal > 31)
1042 return -1;
1043
1044 return IntVal;
1045}
1046
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001047int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1048 int CC;
1049
1050 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001051 .Case("msair", 0)
1052 .Case("msacsr", 1)
1053 .Case("msaaccess", 2)
1054 .Case("msasave", 3)
1055 .Case("msamodify", 4)
1056 .Case("msarequest", 5)
1057 .Case("msamap", 6)
1058 .Case("msaunmap", 7)
1059 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001060
1061 return CC;
1062}
1063
Vladimir Medic8cd17102013-06-20 11:21:49 +00001064int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1065
Vladimir Medic8cd17102013-06-20 11:21:49 +00001066 int CC;
1067 CC = matchCPURegisterName(Name);
1068 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001069 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1070 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001071 CC = matchFPURegisterName(Name);
Vladimir Medic4c299852013-11-06 11:27:05 +00001072 // TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001073 if (CC != -1)
1074 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1075 : Mips::FGR32RegClassID);
1076 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001077}
1078
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001079int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001080
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001081 switch (RegKind) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001082 case MipsOperand::Kind_GPR32:
1083 return Mips::GPR32RegClassID;
1084 case MipsOperand::Kind_GPR64:
1085 return Mips::GPR64RegClassID;
1086 case MipsOperand::Kind_HWRegs:
1087 return Mips::HWRegsRegClassID;
1088 case MipsOperand::Kind_FGR32Regs:
1089 return Mips::FGR32RegClassID;
1090 case MipsOperand::Kind_FGRH32Regs:
1091 return Mips::FGRH32RegClassID;
1092 case MipsOperand::Kind_FGR64Regs:
1093 return Mips::FGR64RegClassID;
1094 case MipsOperand::Kind_AFGR64Regs:
1095 return Mips::AFGR64RegClassID;
1096 case MipsOperand::Kind_CCRRegs:
1097 return Mips::CCRRegClassID;
1098 case MipsOperand::Kind_ACC64DSP:
1099 return Mips::ACC64DSPRegClassID;
1100 case MipsOperand::Kind_FCCRegs:
1101 return Mips::FCCRegClassID;
1102 case MipsOperand::Kind_MSA128BRegs:
1103 return Mips::MSA128BRegClassID;
1104 case MipsOperand::Kind_MSA128HRegs:
1105 return Mips::MSA128HRegClassID;
1106 case MipsOperand::Kind_MSA128WRegs:
1107 return Mips::MSA128WRegClassID;
1108 case MipsOperand::Kind_MSA128DRegs:
1109 return Mips::MSA128DRegClassID;
1110 case MipsOperand::Kind_MSA128CtrlRegs:
1111 return Mips::MSACtrlRegClassID;
1112 default:
1113 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001114 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001115}
Jack Carterb4dbc172012-09-05 23:34:03 +00001116
Jack Carter0b744b32012-10-04 02:29:46 +00001117bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1118 if (Reg > 31)
1119 return false;
1120
1121 aTReg = Reg;
1122 return true;
1123}
1124
Vladimir Medic4c299852013-11-06 11:27:05 +00001125int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
Jack Carter0b744b32012-10-04 02:29:46 +00001126
Jack Carterd0bd6422013-04-18 00:41:53 +00001127unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001128 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001129}
1130
Jack Carter873c7242013-01-12 01:03:14 +00001131int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001132 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001133 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001134 return -1;
1135
Jack Carter873c7242013-01-12 01:03:14 +00001136 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001137}
1138
Jack Carter873c7242013-01-12 01:03:14 +00001139int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001140 const AsmToken &Tok = Parser.getTok();
1141 int RegNum = -1;
1142
1143 if (Tok.is(AsmToken::Identifier)) {
1144 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001145 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001146 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001147 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001148 is64BitReg ? Mips::GPR64RegClassID
1149 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001150 return RegNum;
1151}
1152
Jack Carterd0bd6422013-04-18 00:41:53 +00001153bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001154 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001155
1156 SMLoc S = Parser.getTok().getLoc();
1157 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001158
Jack Carter873c7242013-01-12 01:03:14 +00001159 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001160 if (RegNo == -1)
1161 return true;
1162
Vladimir Medic4c299852013-11-06 11:27:05 +00001163 Operands.push_back(
1164 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001165 Parser.Lex(); // Eat register token.
1166 return false;
1167}
1168
Vladimir Medic4c299852013-11-06 11:27:05 +00001169bool
1170MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1171 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001172 // Check if the current operand has a custom associated parser, if so, try to
1173 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001174 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1175 if (ResTy == MatchOperand_Success)
1176 return false;
1177 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1178 // there was a match, but an error occurred, in which case, just return that
1179 // the operand parsing failed.
1180 if (ResTy == MatchOperand_ParseFail)
1181 return true;
1182
1183 switch (getLexer().getKind()) {
1184 default:
1185 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1186 return true;
1187 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001188 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001189 SMLoc S = Parser.getTok().getLoc();
1190 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001191 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001192 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001193 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001194 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001195 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001196 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001197 if (getLexer().isNot(AsmToken::Dollar))
1198 return true;
1199
Jack Carterd0bd6422013-04-18 00:41:53 +00001200 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001201 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001202 return true;
1203
1204 if (!getLexer().is(AsmToken::RParen))
1205 return true;
1206
1207 S = Parser.getTok().getLoc();
1208 Operands.push_back(MipsOperand::CreateToken(")", S));
1209 Parser.Lex();
1210 }
1211 return false;
1212 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001213 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001214 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001215 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001216 return true;
1217
Jack Carter873c7242013-01-12 01:03:14 +00001218 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001219 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001220 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001221 const MCExpr *Res =
1222 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001223
1224 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1225 return false;
1226 }
1227 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001228 // For instruction aliases like "bc1f $Label" dedicated parser will
1229 // eat the '$' sign before failing. So in order to look for appropriate
1230 // label we must check first if we have already consumed '$'.
1231 if (hasConsumedDollar) {
1232 hasConsumedDollar = false;
1233 SMLoc S = Parser.getTok().getLoc();
1234 StringRef Identifier;
1235 if (Parser.parseIdentifier(Identifier))
1236 return true;
1237 SMLoc E =
1238 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1239 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1240 // Create a symbol reference.
1241 const MCExpr *Res =
1242 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1243
1244 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1245 return false;
1246 }
Jack Carterd76b2372013-03-21 21:44:16 +00001247 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001248 // we need to assigne the propper RegisterKind.
1249 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1250 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001251 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001252 case AsmToken::LParen:
1253 case AsmToken::Minus:
1254 case AsmToken::Plus:
1255 case AsmToken::Integer:
1256 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001257 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001258 const MCExpr *IdVal;
1259 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001260 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001261 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001262 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001263 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1264 return false;
1265 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001266 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001267 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001268 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001269 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001270 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001271 return true;
1272
Jack Carter873c7242013-01-12 01:03:14 +00001273 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1274
Jack Carterdc1e35d2012-09-06 20:00:02 +00001275 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1276 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001277 } // case AsmToken::Percent
1278 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001279 return true;
1280}
1281
Vladimir Medic4c299852013-11-06 11:27:05 +00001282const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001283 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001284 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001285 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001286 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001287 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001288 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001289 short Val = MCE->getValue();
1290 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001291 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001292 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001293 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001294 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001295 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001296 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001297 if (LoSign)
1298 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001299 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001300 } else {
1301 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001302 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001303 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001304 }
1305
Jack Carterb5cf5902013-04-17 00:18:04 +00001306 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001307 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001308 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001309 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001310 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001311 return Res;
1312 }
1313
1314 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001315 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1316 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001317 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1318 return Res;
1319 }
1320
1321 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001322 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1323 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1324 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001325 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001326 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001327 return Expr;
1328}
1329
1330bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1331
1332 switch (Expr->getKind()) {
1333 case MCExpr::Constant:
1334 return true;
1335 case MCExpr::SymbolRef:
1336 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1337 case MCExpr::Binary:
1338 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1339 if (!isEvaluated(BE->getLHS()))
1340 return false;
1341 return isEvaluated(BE->getRHS());
1342 }
1343 case MCExpr::Unary:
1344 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1345 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001346 return false;
1347 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001348 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001349}
Jack Carterd0bd6422013-04-18 00:41:53 +00001350
Jack Carterb5cf5902013-04-17 00:18:04 +00001351bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001352 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001353 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001354 if (Tok.isNot(AsmToken::Identifier))
1355 return true;
1356
1357 std::string Str = Tok.getIdentifier().str();
1358
Jack Carterd0bd6422013-04-18 00:41:53 +00001359 Parser.Lex(); // Eat the identifier.
1360 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001361 const MCExpr *IdVal;
1362 SMLoc EndLoc;
1363
1364 if (getLexer().getKind() == AsmToken::LParen) {
1365 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001366 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001367 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001368 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001369 const AsmToken &nextTok = Parser.getTok();
1370 if (nextTok.isNot(AsmToken::Identifier))
1371 return true;
1372 Str += "(%";
1373 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001374 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001375 if (getLexer().getKind() != AsmToken::LParen)
1376 return true;
1377 } else
1378 break;
1379 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001380 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001381 return true;
1382
1383 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001384 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001385
1386 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001387 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001388
Jack Carterd0bd6422013-04-18 00:41:53 +00001389 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001390 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001391}
1392
Jack Carterb4dbc172012-09-05 23:34:03 +00001393bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1394 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001395 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001396 RegNo = tryParseRegister(isMips64());
1397 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001398 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001399}
1400
Jack Carterb5cf5902013-04-17 00:18:04 +00001401bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001402 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001403 bool Result = true;
1404
1405 while (getLexer().getKind() == AsmToken::LParen)
1406 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001407
Jack Carterd0bd6422013-04-18 00:41:53 +00001408 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001409 default:
1410 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001411 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001412 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001413 case AsmToken::Integer:
1414 case AsmToken::Minus:
1415 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001416 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001417 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001418 else
1419 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001420 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001421 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001422 break;
Jack Carter873c7242013-01-12 01:03:14 +00001423 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001424 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001425 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001426 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001427}
1428
Jack Carterb4dbc172012-09-05 23:34:03 +00001429MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001430 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001431
1432 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001433 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001434 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001435 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001436 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001437 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001438
Jack Carterb5cf5902013-04-17 00:18:04 +00001439 if (getLexer().getKind() == AsmToken::LParen) {
1440 Parser.Lex();
1441 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001442 }
1443
Jack Carterb5cf5902013-04-17 00:18:04 +00001444 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001445 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001446 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001447
Jack Carterd0bd6422013-04-18 00:41:53 +00001448 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001449 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001450 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001451 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001452 SMLoc E =
1453 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001454 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1455 return MatchOperand_Success;
1456 }
1457 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001458 SMLoc E =
1459 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001460
Jack Carterd0bd6422013-04-18 00:41:53 +00001461 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001462 Operands.push_back(MipsOperand::CreateMem(
1463 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001464 return MatchOperand_Success;
1465 }
1466 Error(Parser.getTok().getLoc(), "'(' expected");
1467 return MatchOperand_ParseFail;
1468 }
1469
Jack Carterd0bd6422013-04-18 00:41:53 +00001470 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001471 }
1472
Vladimir Medic4c299852013-11-06 11:27:05 +00001473 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1474 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001475 if (Res != MatchOperand_Success)
1476 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001477
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001478 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001479 Error(Parser.getTok().getLoc(), "')' expected");
1480 return MatchOperand_ParseFail;
1481 }
1482
Jack Carter873c7242013-01-12 01:03:14 +00001483 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1484
Jack Carterd0bd6422013-04-18 00:41:53 +00001485 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001486
1487 if (IdVal == 0)
1488 IdVal = MCConstantExpr::Create(0, getContext());
1489
Jack Carterd0bd6422013-04-18 00:41:53 +00001490 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001491 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001492 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001493 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001494 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001495 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001496 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1497 int64_t Imm;
1498 if (IdVal->EvaluateAsAbsolute(Imm))
1499 IdVal = MCConstantExpr::Create(Imm, getContext());
1500 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1501 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1502 getContext());
1503 }
1504
Jack Carterdc1e35d2012-09-06 20:00:02 +00001505 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1506 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001507 return MatchOperand_Success;
1508}
1509
Vladimir Medic4c299852013-11-06 11:27:05 +00001510bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1511 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001512 // If the first token is not '$' we have an error.
1513 if (Parser.getTok().isNot(AsmToken::Dollar))
1514 return false;
1515
1516 SMLoc S = Parser.getTok().getLoc();
1517 Parser.Lex();
1518 AsmToken::TokenKind TkKind = getLexer().getKind();
1519 int Reg;
1520
1521 if (TkKind == AsmToken::Integer) {
1522 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1523 regKindToRegClass(RegKind));
1524 if (Reg == -1)
1525 return false;
1526 } else if (TkKind == AsmToken::Identifier) {
1527 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1528 return false;
1529 Reg = getReg(regKindToRegClass(RegKind), Reg);
1530 } else {
1531 return false;
1532 }
1533
1534 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1535 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1536 Operands.push_back(Op);
1537 Parser.Lex();
1538 return true;
1539}
1540
1541MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001542MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1543 MipsOperand::RegisterKind RegKind =
1544 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001545
1546 // Parse index register.
1547 if (!parsePtrReg(Operands, RegKind))
1548 return MatchOperand_NoMatch;
1549
1550 // Parse '('.
1551 if (Parser.getTok().isNot(AsmToken::LParen))
1552 return MatchOperand_NoMatch;
1553
1554 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1555 Parser.Lex();
1556
1557 // Parse base register.
1558 if (!parsePtrReg(Operands, RegKind))
1559 return MatchOperand_NoMatch;
1560
1561 // Parse ')'.
1562 if (Parser.getTok().isNot(AsmToken::RParen))
1563 return MatchOperand_NoMatch;
1564
1565 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1566 Parser.Lex();
1567
1568 return MatchOperand_Success;
1569}
1570
Jack Carter873c7242013-01-12 01:03:14 +00001571MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001572MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001573 int RegKind) {
1574 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001575 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001576 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001577 return MatchOperand_Success;
1578 return MatchOperand_NoMatch;
1579 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001580 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001581 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001582 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001583 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001584 if (!hasConsumedDollar) {
1585 Parser.Lex(); // Eat the '$'
1586 hasConsumedDollar = true;
1587 }
1588 if (getLexer().getKind() == AsmToken::Identifier) {
1589 int RegNum = -1;
1590 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001591 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001592 switch (RegKind) {
1593 case MipsOperand::Kind_GPR32:
1594 case MipsOperand::Kind_GPR64:
1595 RegNum = matchCPURegisterName(RegName);
1596 break;
1597 case MipsOperand::Kind_AFGR64Regs:
1598 case MipsOperand::Kind_FGR64Regs:
1599 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001600 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001601 RegNum = matchFPURegisterName(RegName);
1602 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1603 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001604 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1605 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001606 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001607 break;
1608 case MipsOperand::Kind_FCCRegs:
1609 RegNum = matchFCCRegisterName(RegName);
1610 break;
1611 case MipsOperand::Kind_ACC64DSP:
1612 RegNum = matchACRegisterName(RegName);
1613 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001614 default:
1615 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001616 }
1617 // No match found, return _NoMatch to give a chance to other round.
1618 if (RegNum < 0)
1619 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001620
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001621 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1622 if (RegVal == -1)
1623 return MatchOperand_NoMatch;
1624
Vladimir Medic4c299852013-11-06 11:27:05 +00001625 MipsOperand *Op =
1626 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001627 Op->setRegKind(Kind);
1628 Operands.push_back(Op);
1629 hasConsumedDollar = false;
1630 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001631 return MatchOperand_Success;
1632 } else if (getLexer().getKind() == AsmToken::Integer) {
1633 unsigned RegNum = Parser.getTok().getIntVal();
1634 if (Kind == MipsOperand::Kind_HWRegs) {
1635 if (RegNum != 29)
1636 return MatchOperand_NoMatch;
1637 // Only hwreg 29 is supported, found at index 0.
1638 RegNum = 0;
1639 }
1640 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1641 if (Reg == -1)
1642 return MatchOperand_NoMatch;
1643 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1644 Op->setRegKind(Kind);
1645 Operands.push_back(Op);
1646 hasConsumedDollar = false;
1647 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001648 if ((RegKind == MipsOperand::Kind_GPR32) &&
1649 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001650 // Check if it is indexed addressing operand.
1651 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1652 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001653 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001654 return MatchOperand_NoMatch;
1655 if (getLexer().isNot(AsmToken::RParen))
1656 return MatchOperand_NoMatch;
1657 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1658 Parser.Lex();
1659 }
Jack Carter873c7242013-01-12 01:03:14 +00001660 return MatchOperand_Success;
1661 }
1662 return MatchOperand_NoMatch;
1663}
Vladimir Medic64828a12013-07-16 10:07:14 +00001664
Matheus Almeidab74293d2013-10-14 11:49:30 +00001665bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1666 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1667
1668 if (Val < 0)
1669 return false;
1670
1671 switch (Kind) {
1672 default:
1673 return false;
1674 case MipsOperand::Kind_MSA128BRegs:
1675 return Val < 16;
1676 case MipsOperand::Kind_MSA128HRegs:
1677 return Val < 8;
1678 case MipsOperand::Kind_MSA128WRegs:
1679 return Val < 4;
1680 case MipsOperand::Kind_MSA128DRegs:
1681 return Val < 2;
1682 }
1683}
1684
Vladimir Medic8cd17102013-06-20 11:21:49 +00001685MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001686MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001687 int RegKind) {
1688 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1689 SMLoc S = Parser.getTok().getLoc();
1690 std::string RegName;
1691
1692 if (Parser.getTok().isNot(AsmToken::Dollar))
1693 return MatchOperand_NoMatch;
1694
1695 switch (RegKind) {
1696 default:
1697 return MatchOperand_ParseFail;
1698 case MipsOperand::Kind_MSA128BRegs:
1699 case MipsOperand::Kind_MSA128HRegs:
1700 case MipsOperand::Kind_MSA128WRegs:
1701 case MipsOperand::Kind_MSA128DRegs:
1702 break;
1703 }
1704
1705 Parser.Lex(); // Eat the '$'.
1706 if (getLexer().getKind() == AsmToken::Identifier)
1707 RegName = Parser.getTok().getString().lower();
1708 else
1709 return MatchOperand_ParseFail;
1710
1711 int RegNum = matchMSA128RegisterName(RegName);
1712
1713 if (RegNum < 0 || RegNum > 31)
1714 return MatchOperand_ParseFail;
1715
1716 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1717 if (RegVal == -1)
1718 return MatchOperand_ParseFail;
1719
Vladimir Medic4c299852013-11-06 11:27:05 +00001720 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001721 Op->setRegKind(Kind);
1722 Operands.push_back(Op);
1723
1724 Parser.Lex(); // Eat the register identifier.
1725
Matheus Almeidab74293d2013-10-14 11:49:30 +00001726 // MSA registers may be suffixed with an index in the form of:
1727 // 1) Immediate expression.
1728 // 2) General Purpose Register.
1729 // Examples:
1730 // 1) copy_s.b $29,$w0[0]
1731 // 2) sld.b $w0,$w1[$1]
1732
1733 if (Parser.getTok().isNot(AsmToken::LBrac))
1734 return MatchOperand_Success;
1735
1736 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1737
1738 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1739 Parser.Lex(); // Parse the '[' token.
1740
1741 if (Parser.getTok().is(AsmToken::Dollar)) {
1742 // This must be a GPR.
1743 MipsOperand *RegOp;
1744 SMLoc VIdx = Parser.getTok().getLoc();
1745 Parser.Lex(); // Parse the '$' token.
1746
1747 // GPR have aliases and we must account for that. Example: $30 == $fp
1748 if (getLexer().getKind() == AsmToken::Integer) {
1749 unsigned RegNum = Parser.getTok().getIntVal();
1750 int Reg = matchRegisterByNumber(
1751 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1752 if (Reg == -1) {
1753 Error(VIdx, "invalid general purpose register");
1754 return MatchOperand_ParseFail;
1755 }
1756
1757 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1758 } else if (getLexer().getKind() == AsmToken::Identifier) {
1759 int RegNum = -1;
1760 std::string RegName = Parser.getTok().getString().lower();
1761
1762 RegNum = matchCPURegisterName(RegName);
1763 if (RegNum == -1) {
1764 Error(VIdx, "general purpose register expected");
1765 return MatchOperand_ParseFail;
1766 }
1767 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1768 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1769 } else
1770 return MatchOperand_ParseFail;
1771
1772 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1773 Operands.push_back(RegOp);
1774 Parser.Lex(); // Eat the register identifier.
1775
1776 if (Parser.getTok().isNot(AsmToken::RBrac))
1777 return MatchOperand_ParseFail;
1778
1779 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1780 Parser.Lex(); // Parse the ']' token.
1781
1782 return MatchOperand_Success;
1783 }
1784
1785 // The index must be a constant expression then.
1786 SMLoc VIdx = Parser.getTok().getLoc();
1787 const MCExpr *ImmVal;
1788
1789 if (getParser().parseExpression(ImmVal))
1790 return MatchOperand_ParseFail;
1791
1792 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1793 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1794 Error(VIdx, "invalid immediate value");
1795 return MatchOperand_ParseFail;
1796 }
1797
1798 SMLoc E = Parser.getTok().getEndLoc();
1799
1800 if (Parser.getTok().isNot(AsmToken::RBrac))
1801 return MatchOperand_ParseFail;
1802
Vladimir Medic4c299852013-11-06 11:27:05 +00001803 bool insve =
1804 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1805 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001806
1807 // The second vector index of insve instructions is always 0.
1808 if (insve && Operands.size() > 6) {
1809 if (expr->getValue() != 0) {
1810 Error(VIdx, "immediate value must be 0");
1811 return MatchOperand_ParseFail;
1812 }
1813 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1814 } else
1815 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1816
1817 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1818
1819 Parser.Lex(); // Parse the ']' token.
1820
Jack Carter5dc8ac92013-09-25 23:50:44 +00001821 return MatchOperand_Success;
1822}
1823
1824MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001825MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1826 int RegKind) {
1827 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1828
1829 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1830 return MatchOperand_NoMatch;
1831
1832 if (Parser.getTok().isNot(AsmToken::Dollar))
1833 return MatchOperand_ParseFail;
1834
1835 SMLoc S = Parser.getTok().getLoc();
1836
1837 Parser.Lex(); // Eat the '$' symbol.
1838
1839 int RegNum = -1;
1840 if (getLexer().getKind() == AsmToken::Identifier)
1841 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1842 else if (getLexer().getKind() == AsmToken::Integer)
1843 RegNum = Parser.getTok().getIntVal();
1844 else
1845 return MatchOperand_ParseFail;
1846
1847 if (RegNum < 0 || RegNum > 7)
1848 return MatchOperand_ParseFail;
1849
1850 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1851 if (RegVal == -1)
1852 return MatchOperand_ParseFail;
1853
Vladimir Medic4c299852013-11-06 11:27:05 +00001854 MipsOperand *RegOp =
1855 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001856 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1857 Operands.push_back(RegOp);
1858 Parser.Lex(); // Eat the register identifier.
1859
1860 return MatchOperand_Success;
1861}
1862
1863MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001864MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001865
1866 if (!isMips64())
1867 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001868 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001869}
1870
1871MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001872MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1873 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001874}
Jack Carter873c7242013-01-12 01:03:14 +00001875
Vladimir Medic4c299852013-11-06 11:27:05 +00001876MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1877 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001878
1879 if (isFP64())
1880 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001881 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001882}
1883
1884MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001885MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001886 if (!isFP64())
1887 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001888 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001889}
1890
1891MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001892MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1893 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1894}
1895
1896MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1897 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1898 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001899}
1900
Vladimir Medic643b3982013-07-30 10:12:14 +00001901MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001902MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1903 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001904}
1905
1906MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001907MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1908 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001909}
1910
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001911MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001912MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001913 // If the first token is not '$' we have an error.
1914 if (Parser.getTok().isNot(AsmToken::Dollar))
1915 return MatchOperand_NoMatch;
1916
1917 SMLoc S = Parser.getTok().getLoc();
1918 Parser.Lex(); // Eat the '$'
1919
1920 const AsmToken &Tok = Parser.getTok(); // Get next token.
1921
1922 if (Tok.isNot(AsmToken::Identifier))
1923 return MatchOperand_NoMatch;
1924
1925 if (!Tok.getIdentifier().startswith("ac"))
1926 return MatchOperand_NoMatch;
1927
1928 StringRef NumString = Tok.getIdentifier().substr(2);
1929
1930 unsigned IntVal;
1931 if (NumString.getAsInteger(10, IntVal))
1932 return MatchOperand_NoMatch;
1933
1934 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1935
1936 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1937 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1938 Operands.push_back(Op);
1939
1940 Parser.Lex(); // Eat the register number.
1941 return MatchOperand_Success;
1942}
1943
1944MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001945MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001946 // If the first token is not '$' we have an error.
1947 if (Parser.getTok().isNot(AsmToken::Dollar))
1948 return MatchOperand_NoMatch;
1949
1950 SMLoc S = Parser.getTok().getLoc();
1951 Parser.Lex(); // Eat the '$'
1952
1953 const AsmToken &Tok = Parser.getTok(); // Get next token.
1954
1955 if (Tok.isNot(AsmToken::Identifier))
1956 return MatchOperand_NoMatch;
1957
1958 if (!Tok.getIdentifier().startswith("ac"))
1959 return MatchOperand_NoMatch;
1960
1961 StringRef NumString = Tok.getIdentifier().substr(2);
1962
1963 unsigned IntVal;
1964 if (NumString.getAsInteger(10, IntVal))
1965 return MatchOperand_NoMatch;
1966
1967 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1968
1969 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1970 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1971 Operands.push_back(Op);
1972
1973 Parser.Lex(); // Eat the register number.
1974 return MatchOperand_Success;
1975}
1976
Vladimir Medic05bcde62013-09-16 10:29:42 +00001977MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001978MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00001979 // If the first token is not '$' we have an error.
1980 if (Parser.getTok().isNot(AsmToken::Dollar))
1981 return MatchOperand_NoMatch;
1982
1983 SMLoc S = Parser.getTok().getLoc();
1984 Parser.Lex(); // Eat the '$'
1985
1986 const AsmToken &Tok = Parser.getTok(); // Get next token.
1987
1988 if (Tok.isNot(AsmToken::Integer))
1989 return MatchOperand_NoMatch;
1990
1991 unsigned IntVal = Tok.getIntVal();
1992
1993 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1994
1995 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1996 Op->setRegKind(MipsOperand::Kind_COP2);
1997 Operands.push_back(Op);
1998
1999 Parser.Lex(); // Eat the register number.
2000 return MatchOperand_Success;
2001}
2002
Vladimir Medic4c299852013-11-06 11:27:05 +00002003MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2004 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2005 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002006}
2007
Vladimir Medic4c299852013-11-06 11:27:05 +00002008MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2009 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2010 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002011}
2012
Vladimir Medic4c299852013-11-06 11:27:05 +00002013MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2014 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2015 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002016}
2017
Vladimir Medic4c299852013-11-06 11:27:05 +00002018MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2019 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2020 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002021}
2022
Vladimir Medic4c299852013-11-06 11:27:05 +00002023MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2024 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2025 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002026}
2027
Jack Carterd0bd6422013-04-18 00:41:53 +00002028bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002029 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002030
2031 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2032 if (Sym) {
2033 SMLoc S = Parser.getTok().getLoc();
2034 const MCExpr *Expr;
2035 if (Sym->isVariable())
2036 Expr = Sym->getVariableValue();
2037 else
2038 return false;
2039 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002040 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2041 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002042 const StringRef DefSymbol = Ref->getSymbol().getName();
2043 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002044 int RegNum = -1;
2045 APInt IntVal(32, -1);
2046 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2047 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002048 isMips64() ? Mips::GPR64RegClassID
2049 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002050 else {
2051 // Lookup for the register with the corresponding name.
2052 switch (Kind) {
2053 case MipsOperand::Kind_AFGR64Regs:
2054 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002055 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002056 break;
2057 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002058 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002059 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002060 case MipsOperand::Kind_GPR64:
2061 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002062 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002063 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002064 break;
2065 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002066 if (RegNum > -1)
2067 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002068 }
Jack Carterd76b2372013-03-21 21:44:16 +00002069 if (RegNum > -1) {
2070 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002071 MipsOperand *op =
2072 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002073 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002074 Operands.push_back(op);
2075 return true;
2076 }
2077 }
2078 } else if (Expr->getKind() == MCExpr::Constant) {
2079 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002080 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2081 MipsOperand *op =
2082 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002083 Operands.push_back(op);
2084 return true;
2085 }
2086 }
2087 return false;
2088}
Jack Carterd0bd6422013-04-18 00:41:53 +00002089
Jack Carter873c7242013-01-12 01:03:14 +00002090MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002091MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2092 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002093}
2094
2095MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002096MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2097 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002098}
2099
Vladimir Medic2b953d02013-10-01 09:48:56 +00002100MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002101MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002102 const MCExpr *IdVal;
2103 // If the first token is '$' we may have register operand.
2104 if (Parser.getTok().is(AsmToken::Dollar))
2105 return MatchOperand_NoMatch;
2106 SMLoc S = Parser.getTok().getLoc();
2107 if (getParser().parseExpression(IdVal))
2108 return MatchOperand_ParseFail;
2109 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002110 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002111 int64_t Val = MCE->getValue();
2112 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2113 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002114 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002115 return MatchOperand_Success;
2116}
2117
Matheus Almeida779c5932013-11-18 12:32:49 +00002118MipsAsmParser::OperandMatchResultTy
2119MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2120 switch (getLexer().getKind()) {
2121 default:
2122 return MatchOperand_NoMatch;
2123 case AsmToken::LParen:
2124 case AsmToken::Plus:
2125 case AsmToken::Minus:
2126 case AsmToken::Integer:
2127 break;
2128 }
2129
2130 const MCExpr *Expr;
2131 SMLoc S = Parser.getTok().getLoc();
2132
2133 if (getParser().parseExpression(Expr))
2134 return MatchOperand_ParseFail;
2135
2136 int64_t Val;
2137 if (!Expr->EvaluateAsAbsolute(Val)) {
2138 Error(S, "expected immediate value");
2139 return MatchOperand_ParseFail;
2140 }
2141
2142 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2143 // and because the CPU always adds one to the immediate field, the allowed
2144 // range becomes 1..4. We'll only check the range here and will deal
2145 // with the addition/subtraction when actually decoding/encoding
2146 // the instruction.
2147 if (Val < 1 || Val > 4) {
2148 Error(S, "immediate not in range (1..4)");
2149 return MatchOperand_ParseFail;
2150 }
2151
2152 Operands.push_back(MipsOperand::CreateLSAImm(Expr, S,
2153 Parser.getTok().getLoc()));
2154 return MatchOperand_Success;
2155}
2156
Jack Carterdc1e35d2012-09-06 20:00:02 +00002157MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2158
Vladimir Medic4c299852013-11-06 11:27:05 +00002159 MCSymbolRefExpr::VariantKind VK =
2160 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2161 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2162 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2163 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2164 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2165 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2166 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2167 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2168 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2169 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2170 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2171 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2172 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2173 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2174 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2175 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2176 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2177 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2178 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002179
2180 return VK;
2181}
Jack Cartera63b16a2012-09-07 00:23:42 +00002182
Vladimir Medic4c299852013-11-06 11:27:05 +00002183bool MipsAsmParser::ParseInstruction(
2184 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2185 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002186 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002187 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002188 Parser.eatToEndOfStatement();
2189 return Error(NameLoc, "Unknown instruction");
2190 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002191 // First operand in MCInst is instruction mnemonic.
2192 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002193
2194 // Read the remaining operands.
2195 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2196 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002197 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002198 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002199 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002200 return Error(Loc, "unexpected token in argument list");
2201 }
2202
Jack Carterd0bd6422013-04-18 00:41:53 +00002203 while (getLexer().is(AsmToken::Comma)) {
2204 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002205 // Parse and remember the operand.
2206 if (ParseOperand(Operands, Name)) {
2207 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002208 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002209 return Error(Loc, "unexpected token in argument list");
2210 }
2211 }
2212 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002213 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2214 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002215 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002216 return Error(Loc, "unexpected token in argument list");
2217 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002218 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002219 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002220}
2221
Jack Carter0b744b32012-10-04 02:29:46 +00002222bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002223 SMLoc Loc = getLexer().getLoc();
2224 Parser.eatToEndOfStatement();
2225 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002226}
2227
2228bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002229 // Line should look like: ".set noat".
2230 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002231 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002232 // eat noat
2233 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002234 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002235 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2236 reportParseError("unexpected token in statement");
2237 return false;
2238 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002239 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002240 return false;
2241}
Jack Carterd0bd6422013-04-18 00:41:53 +00002242
Jack Carter0b744b32012-10-04 02:29:46 +00002243bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002244 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002245 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002246 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002247 getParser().Lex();
2248 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002249 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002250 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002251 return false;
2252 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002253 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002254 if (getLexer().isNot(AsmToken::Dollar)) {
2255 reportParseError("unexpected token in statement");
2256 return false;
2257 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002258 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002259 const AsmToken &Reg = Parser.getTok();
2260 if (Reg.is(AsmToken::Identifier)) {
2261 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2262 } else if (Reg.is(AsmToken::Integer)) {
2263 AtRegNo = Reg.getIntVal();
2264 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002265 reportParseError("unexpected token in statement");
2266 return false;
2267 }
Jack Carter1ac53222013-02-20 23:11:17 +00002268
Jack Carterd0bd6422013-04-18 00:41:53 +00002269 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002270 reportParseError("unexpected token in statement");
2271 return false;
2272 }
2273
2274 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002275 reportParseError("unexpected token in statement");
2276 return false;
2277 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002278 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002279
2280 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2281 reportParseError("unexpected token in statement");
2282 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002283 }
2284 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002285 return false;
2286 } else {
2287 reportParseError("unexpected token in statement");
2288 return false;
2289 }
2290}
2291
2292bool MipsAsmParser::parseSetReorderDirective() {
2293 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002294 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002295 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2296 reportParseError("unexpected token in statement");
2297 return false;
2298 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002299 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002300 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002301 return false;
2302}
2303
2304bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002305 Parser.Lex();
2306 // If this is not the end of the statement, report an error.
2307 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2308 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002309 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002310 }
2311 Options.setNoreorder();
2312 Parser.Lex(); // Consume the EndOfStatement.
2313 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002314}
2315
2316bool MipsAsmParser::parseSetMacroDirective() {
2317 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002318 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002319 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2320 reportParseError("unexpected token in statement");
2321 return false;
2322 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002323 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002324 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002325 return false;
2326}
2327
2328bool MipsAsmParser::parseSetNoMacroDirective() {
2329 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002330 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2332 reportParseError("`noreorder' must be set before `nomacro'");
2333 return false;
2334 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002335 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002336 reportParseError("`noreorder' must be set before `nomacro'");
2337 return false;
2338 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002339 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002340 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002341 return false;
2342}
Jack Carterd76b2372013-03-21 21:44:16 +00002343
2344bool MipsAsmParser::parseSetAssignment() {
2345 StringRef Name;
2346 const MCExpr *Value;
2347
2348 if (Parser.parseIdentifier(Name))
2349 reportParseError("expected identifier after .set");
2350
2351 if (getLexer().isNot(AsmToken::Comma))
2352 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002353 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002354
Vladimir Medic0d02be32013-12-09 11:03:25 +00002355 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002356 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002357
Jack Carterd0bd6422013-04-18 00:41:53 +00002358 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002359 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002360 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002361 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002362 Sym = getContext().GetOrCreateSymbol(Name);
2363 Sym->setVariableValue(Value);
2364
2365 return false;
2366}
Jack Carterd0bd6422013-04-18 00:41:53 +00002367
Jack Carter0b744b32012-10-04 02:29:46 +00002368bool MipsAsmParser::parseDirectiveSet() {
2369
Jack Carterd0bd6422013-04-18 00:41:53 +00002370 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002371 const AsmToken &Tok = Parser.getTok();
2372
2373 if (Tok.getString() == "noat") {
2374 return parseSetNoAtDirective();
2375 } else if (Tok.getString() == "at") {
2376 return parseSetAtDirective();
2377 } else if (Tok.getString() == "reorder") {
2378 return parseSetReorderDirective();
2379 } else if (Tok.getString() == "noreorder") {
2380 return parseSetNoReorderDirective();
2381 } else if (Tok.getString() == "macro") {
2382 return parseSetMacroDirective();
2383 } else if (Tok.getString() == "nomacro") {
2384 return parseSetNoMacroDirective();
2385 } else if (Tok.getString() == "nomips16") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002386 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002387 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002388 return false;
2389 } else if (Tok.getString() == "nomicromips") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002390 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002391 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002392 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002393 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002394 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002395 parseSetAssignment();
2396 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002397 }
Jack Carter07c818d2013-01-25 01:31:34 +00002398
Jack Carter0b744b32012-10-04 02:29:46 +00002399 return true;
2400}
2401
Jack Carter6ef6cc52013-11-19 20:53:28 +00002402bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2403 MCAsmParser &Parser = getParser();
2404 StringRef Name;
2405 if (Parser.parseIdentifier(Name))
2406 reportParseError("expected identifier");
2407
2408 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2409 if (getLexer().isNot(AsmToken::Comma))
2410 return TokError("unexpected token");
2411 Lex();
2412
2413 int64_t Flags = 0;
2414 if (Parser.parseAbsoluteExpression(Flags))
2415 return TokError("unexpected token");
2416
2417 getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
2418 return false;
2419}
2420
2421bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2422 int64_t Flags = 0;
2423 if (Parser.parseAbsoluteExpression(Flags))
2424 return TokError("unexpected token");
2425
2426 getTargetStreamer().emitMipsHackELFFlags(Flags);
2427 return false;
2428}
2429
Jack Carter07c818d2013-01-25 01:31:34 +00002430/// parseDirectiveWord
2431/// ::= .word [ expression (, expression)* ]
2432bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2433 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2434 for (;;) {
2435 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002436 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002437 return true;
2438
2439 getParser().getStreamer().EmitValue(Value, Size);
2440
2441 if (getLexer().is(AsmToken::EndOfStatement))
2442 break;
2443
2444 // FIXME: Improve diagnostic.
2445 if (getLexer().isNot(AsmToken::Comma))
2446 return Error(L, "unexpected token in directive");
2447 Parser.Lex();
2448 }
2449 }
2450
2451 Parser.Lex();
2452 return false;
2453}
2454
Vladimir Medic4c299852013-11-06 11:27:05 +00002455/// parseDirectiveGpWord
2456/// ::= .gpword local_sym
2457bool MipsAsmParser::parseDirectiveGpWord() {
2458 const MCExpr *Value;
2459 // EmitGPRel32Value requires an expression, so we are using base class
2460 // method to evaluate the expression.
2461 if (getParser().parseExpression(Value))
2462 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002463 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002464
Vladimir Medice10c1122013-11-13 13:18:04 +00002465 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002466 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002467 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002468 return false;
2469}
2470
Jack Carter0b744b32012-10-04 02:29:46 +00002471bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carterbe332172012-09-07 00:48:02 +00002472
Jack Carter07c818d2013-01-25 01:31:34 +00002473 StringRef IDVal = DirectiveID.getString();
2474
Jack Carterd0bd6422013-04-18 00:41:53 +00002475 if (IDVal == ".ent") {
2476 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002477 Parser.Lex();
2478 return false;
2479 }
2480
Jack Carter07c818d2013-01-25 01:31:34 +00002481 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002482 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002483 Parser.Lex();
2484 return false;
2485 }
2486
Jack Carter07c818d2013-01-25 01:31:34 +00002487 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002488 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002489 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002490 return false;
2491 }
2492
Jack Carter07c818d2013-01-25 01:31:34 +00002493 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002494 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002495 }
2496
Jack Carter07c818d2013-01-25 01:31:34 +00002497 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002498 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002499 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002500 return false;
2501 }
2502
Jack Carter07c818d2013-01-25 01:31:34 +00002503 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002504 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002505 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002506 return false;
2507 }
2508
Jack Carter07c818d2013-01-25 01:31:34 +00002509 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002510 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002511 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002512 return false;
2513 }
2514
Jack Carter07c818d2013-01-25 01:31:34 +00002515 if (IDVal == ".word") {
2516 parseDirectiveWord(4, DirectiveID.getLoc());
2517 return false;
2518 }
2519
Jack Carter6ef6cc52013-11-19 20:53:28 +00002520 if (IDVal == ".mips_hack_stocg")
2521 return parseDirectiveMipsHackStocg();
2522
2523 if (IDVal == ".mips_hack_elf_flags")
2524 return parseDirectiveMipsHackELFFlags();
2525
Rafael Espindola870c4e92012-01-11 03:56:41 +00002526 return true;
2527}
2528
Rafael Espindola870c4e92012-01-11 03:56:41 +00002529extern "C" void LLVMInitializeMipsAsmParser() {
2530 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2531 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2532 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2533 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2534}
Jack Carterb4dbc172012-09-05 23:34:03 +00002535
2536#define GET_REGISTER_MATCHER
2537#define GET_MATCHER_IMPLEMENTATION
2538#include "MipsGenAsmMatcher.inc"