blob: 594ff4f441197af7383325a3551e9d720706b837 [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"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000013#include "llvm/ADT/APInt.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000014#include "llvm/ADT/StringSwitch.h"
15#include "llvm/MC/MCContext.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCInst.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000018#include "llvm/MC/MCParser/MCAsmLexer.h"
19#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000020#include "llvm/MC/MCStreamer.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000023#include "llvm/MC/MCTargetAsmParser.h"
Matheus Almeidae0d75aa2013-12-13 11:11:02 +000024#include "llvm/Support/MathExtras.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000025#include "llvm/Support/TargetRegistry.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() {
Rafael Espindola4a1a3602014-01-14 01:21:46 +000060 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
Rafael Espindolaa17151a2013-10-08 13:08:17 +000061 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
Jack Carter3b2c96e2014-01-22 23:31:38 +0000164 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 parseDirectiveMipsHackELFFlags();
Jack Carter0cd3c192014-01-06 23:27:31 +0000198 bool parseDirectiveOption();
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();
Jack Carter39536722014-01-22 23:08:42 +0000206 bool parseSetMips16Directive();
207 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000208
Jack Carterd76b2372013-03-21 21:44:16 +0000209 bool parseSetAssignment();
210
Jack Carter07c818d2013-01-25 01:31:34 +0000211 bool parseDirectiveWord(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000212 bool parseDirectiveGpWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000213
Jack Carterdc1e35d2012-09-06 20:00:02 +0000214 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000215
Jack Carterb4dbc172012-09-05 23:34:03 +0000216 bool isMips64() const {
217 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
218 }
219
Jack Cartera63b16a2012-09-07 00:23:42 +0000220 bool isFP64() const {
221 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
222 }
223
Vladimir Medic4c299852013-11-06 11:27:05 +0000224 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000225
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000226 bool isMicroMips() const {
227 return STI.getFeatureBits() & Mips::FeatureMicroMips;
228 }
229
Jack Carter873c7242013-01-12 01:03:14 +0000230 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000231
Jack Carter1ac53222013-02-20 23:11:17 +0000232 int matchCPURegisterName(StringRef Symbol);
233
Jack Carter873c7242013-01-12 01:03:14 +0000234 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000235
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000236 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000237
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000238 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000239
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000240 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000241
Jack Carter5dc8ac92013-09-25 23:50:44 +0000242 int matchMSA128RegisterName(StringRef Name);
243
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000244 int matchMSA128CtrlRegisterName(StringRef Name);
245
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000246 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000247
Jack Carterd0bd6422013-04-18 00:41:53 +0000248 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000249
Jack Carter1ac53222013-02-20 23:11:17 +0000250 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000251
252 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000253 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000254
255 // Helper function that checks if the value of a vector index is within the
256 // boundaries of accepted values for each RegisterKind
257 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
258 bool validateMSAIndex(int Val, int RegKind);
259
Rafael Espindola870c4e92012-01-11 03:56:41 +0000260public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000261 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
262 const MCInstrInfo &MII)
263 : MCTargetAsmParser(), STI(sti), Parser(parser),
264 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000265 // Initialize the set of available features.
266 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000267 }
268
Jack Carterb4dbc172012-09-05 23:34:03 +0000269 MCAsmParser &getParser() const { return Parser; }
270 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000271};
272}
273
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000274namespace {
275
276/// MipsOperand - Instances of this class represent a parsed Mips machine
277/// instruction.
278class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000279
Jack Carter873c7242013-01-12 01:03:14 +0000280public:
281 enum RegisterKind {
282 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000283 Kind_GPR32,
284 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000285 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000286 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000287 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000288 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000289 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000290 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000291 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000292 Kind_ACC64DSP,
293 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000294 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000295 Kind_COP2,
296 Kind_MSA128BRegs,
297 Kind_MSA128HRegs,
298 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000299 Kind_MSA128DRegs,
300 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000301 };
302
303private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000304 enum KindTy {
305 k_CondCode,
306 k_CoprocNum,
307 k_Immediate,
308 k_Memory,
309 k_PostIndexRegister,
310 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000311 k_PtrReg,
Matheus Almeida779c5932013-11-18 12:32:49 +0000312 k_Token,
313 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000314 } Kind;
315
316 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000317
Eric Christopher8996c5d2013-03-15 00:42:55 +0000318 struct Token {
319 const char *Data;
320 unsigned Length;
321 };
322
323 struct RegOp {
324 unsigned RegNum;
325 RegisterKind Kind;
326 };
327
328 struct ImmOp {
329 const MCExpr *Val;
330 };
331
332 struct MemOp {
333 unsigned Base;
334 const MCExpr *Off;
335 };
336
Jack Carterb4dbc172012-09-05 23:34:03 +0000337 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000338 struct Token Tok;
339 struct RegOp Reg;
340 struct ImmOp Imm;
341 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000342 };
343
344 SMLoc StartLoc, EndLoc;
345
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000346public:
347 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000348 assert(N == 1 && "Invalid number of operands!");
349 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000350 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000351
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000352 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
353 assert(N == 1 && "Invalid number of operands!");
354 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
355 }
356
Vladimir Medic4c299852013-11-06 11:27:05 +0000357 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000358 // Add as immediate when possible. Null MCExpr = 0.
359 if (Expr == 0)
360 Inst.addOperand(MCOperand::CreateImm(0));
361 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
362 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
363 else
364 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000365 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000366
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000367 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000368 assert(N == 1 && "Invalid number of operands!");
369 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000370 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000371 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000372
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000373 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000374 assert(N == 2 && "Invalid number of operands!");
375
376 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
377
378 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000379 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000380 }
381
382 bool isReg() const { return Kind == k_Register; }
383 bool isImm() const { return Kind == k_Immediate; }
384 bool isToken() const { return Kind == k_Token; }
385 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000386 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000387 bool isInvNum() const { return Kind == k_Immediate; }
Matheus Almeida779c5932013-11-18 12:32:49 +0000388 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000389
390 StringRef getToken() const {
391 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000392 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000393 }
394
395 unsigned getReg() const {
396 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000397 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000398 }
399
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000400 unsigned getPtrReg() const {
401 assert((Kind == k_PtrReg) && "Invalid access!");
402 return Reg.RegNum;
403 }
404
Jack Carter873c7242013-01-12 01:03:14 +0000405 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000406 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000407 Reg.Kind = RegKind;
408 }
409
Jack Carterb4dbc172012-09-05 23:34:03 +0000410 const MCExpr *getImm() const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000411 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000412 return Imm.Val;
413 }
414
Jack Carterdc1e35d2012-09-06 20:00:02 +0000415 unsigned getMemBase() const {
416 assert((Kind == k_Memory) && "Invalid access!");
417 return Mem.Base;
418 }
419
420 const MCExpr *getMemOff() const {
421 assert((Kind == k_Memory) && "Invalid access!");
422 return Mem.Off;
423 }
424
Jack Carterb4dbc172012-09-05 23:34:03 +0000425 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
426 MipsOperand *Op = new MipsOperand(k_Token);
427 Op->Tok.Data = Str.data();
428 Op->Tok.Length = Str.size();
429 Op->StartLoc = S;
430 Op->EndLoc = S;
431 return Op;
432 }
433
434 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
435 MipsOperand *Op = new MipsOperand(k_Register);
436 Op->Reg.RegNum = RegNum;
437 Op->StartLoc = S;
438 Op->EndLoc = E;
439 return Op;
440 }
441
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000442 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
443 MipsOperand *Op = new MipsOperand(k_PtrReg);
444 Op->Reg.RegNum = RegNum;
445 Op->StartLoc = S;
446 Op->EndLoc = E;
447 return Op;
448 }
449
Jack Carterb4dbc172012-09-05 23:34:03 +0000450 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
451 MipsOperand *Op = new MipsOperand(k_Immediate);
452 Op->Imm.Val = Val;
453 Op->StartLoc = S;
454 Op->EndLoc = E;
455 return Op;
456 }
457
Matheus Almeida779c5932013-11-18 12:32:49 +0000458 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
459 MipsOperand *Op = new MipsOperand(k_LSAImm);
460 Op->Imm.Val = Val;
461 Op->StartLoc = S;
462 Op->EndLoc = E;
463 return Op;
464 }
465
Jack Carter3b2c96e2014-01-22 23:31:38 +0000466 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
467 SMLoc E) {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000468 MipsOperand *Op = new MipsOperand(k_Memory);
469 Op->Mem.Base = Base;
470 Op->Mem.Off = Off;
471 Op->StartLoc = S;
472 Op->EndLoc = E;
473 return Op;
474 }
475
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000476 bool isGPR32Asm() const {
477 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000478 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000479 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000480 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
481 }
482
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000483 bool isGPR64Asm() const {
484 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000485 }
Jack Carter873c7242013-01-12 01:03:14 +0000486
487 bool isHWRegsAsm() const {
488 assert((Kind == k_Register) && "Invalid access!");
489 return Reg.Kind == Kind_HWRegs;
490 }
Jack Carter873c7242013-01-12 01:03:14 +0000491
Jack Carter873c7242013-01-12 01:03:14 +0000492 bool isCCRAsm() const {
493 assert((Kind == k_Register) && "Invalid access!");
494 return Reg.Kind == Kind_CCRRegs;
495 }
496
Vladimir Medic4c299852013-11-06 11:27:05 +0000497 bool isAFGR64Asm() const {
Vladimir Medic233dd512013-06-24 10:05:34 +0000498 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
499 }
500
501 bool isFGR64Asm() const {
502 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
503 }
504
505 bool isFGR32Asm() const {
506 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
507 }
508
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000509 bool isFGRH32Asm() const {
510 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
511 }
512
Vladimir Medic643b3982013-07-30 10:12:14 +0000513 bool isFCCRegsAsm() const {
514 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
515 }
516
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000517 bool isACC64DSPAsm() const {
518 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000519 }
520
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000521 bool isLO32DSPAsm() const {
522 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
523 }
524
525 bool isHI32DSPAsm() const {
526 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
527 }
528
Vladimir Medic4c299852013-11-06 11:27:05 +0000529 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
Vladimir Medic05bcde62013-09-16 10:29:42 +0000530
Jack Carter5dc8ac92013-09-25 23:50:44 +0000531 bool isMSA128BAsm() const {
532 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
533 }
534
535 bool isMSA128HAsm() const {
536 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
537 }
538
539 bool isMSA128WAsm() const {
540 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
541 }
542
543 bool isMSA128DAsm() const {
544 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
545 }
546
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000547 bool isMSA128CRAsm() const {
548 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
549 }
550
Jack Carterb4dbc172012-09-05 23:34:03 +0000551 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000552 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000553 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000554 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000555
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000556 virtual void print(raw_ostream &OS) const {
557 llvm_unreachable("unimplemented!");
558 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000559}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000560} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000561
Jack Carter9e65aa32013-03-22 00:05:30 +0000562namespace llvm {
563extern const MCInstrDesc MipsInsts[];
564}
565static const MCInstrDesc &getInstDesc(unsigned Opcode) {
566 return MipsInsts[Opcode];
567}
568
569bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000570 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000571 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
572 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000573
574 if (MCID.isBranch() || MCID.isCall()) {
575 const unsigned Opcode = Inst.getOpcode();
576 MCOperand Offset;
577
578 switch (Opcode) {
579 default:
580 break;
581 case Mips::BEQ:
582 case Mips::BNE:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000583 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000584 Offset = Inst.getOperand(2);
585 if (!Offset.isImm())
586 break; // We'll deal with this situation later on when applying fixups.
587 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
588 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000589 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000590 return Error(IDLoc, "branch to misaligned address");
591 break;
592 case Mips::BGEZ:
593 case Mips::BGTZ:
594 case Mips::BLEZ:
595 case Mips::BLTZ:
596 case Mips::BGEZAL:
597 case Mips::BLTZAL:
598 case Mips::BC1F:
599 case Mips::BC1T:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000600 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000601 Offset = Inst.getOperand(1);
602 if (!Offset.isImm())
603 break; // We'll deal with this situation later on when applying fixups.
604 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
605 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000606 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000607 return Error(IDLoc, "branch to misaligned address");
608 break;
609 }
610 }
611
Jack Carterc15c1d22013-04-25 23:31:35 +0000612 if (MCID.hasDelaySlot() && Options.isReorder()) {
613 // If this instruction has a delay slot and .set reorder is active,
614 // emit a NOP after it.
615 Instructions.push_back(Inst);
616 MCInst NopInst;
617 NopInst.setOpcode(Mips::SLL);
618 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
619 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
620 NopInst.addOperand(MCOperand::CreateImm(0));
621 Instructions.push_back(NopInst);
622 return false;
623 }
624
Jack Carter9e65aa32013-03-22 00:05:30 +0000625 if (MCID.mayLoad() || MCID.mayStore()) {
626 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000627 // reference or immediate we may have to expand instructions.
628 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000629 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000630 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
631 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000632 MCOperand &Op = Inst.getOperand(i);
633 if (Op.isImm()) {
634 int MemOffset = Op.getImm();
635 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000636 // Offset can't exceed 16bit value.
637 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000638 return false;
639 }
640 } else if (Op.isExpr()) {
641 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000642 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000643 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000644 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000645 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000646 // Expand symbol.
647 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000648 return false;
649 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000650 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000651 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000652 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000653 }
654 }
655 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000656 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000657 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000658
659 if (needsExpansion(Inst))
660 expandInstruction(Inst, IDLoc, Instructions);
661 else
662 Instructions.push_back(Inst);
663
664 return false;
665}
666
Jack Carter30a59822012-10-04 04:03:53 +0000667bool MipsAsmParser::needsExpansion(MCInst &Inst) {
668
Jack Carterd0bd6422013-04-18 00:41:53 +0000669 switch (Inst.getOpcode()) {
670 case Mips::LoadImm32Reg:
671 case Mips::LoadAddr32Imm:
672 case Mips::LoadAddr32Reg:
673 return true;
674 default:
675 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000676 }
677}
Jack Carter92995f12012-10-06 00:53:28 +0000678
Jack Carter30a59822012-10-04 04:03:53 +0000679void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000680 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000681 switch (Inst.getOpcode()) {
682 case Mips::LoadImm32Reg:
683 return expandLoadImm(Inst, IDLoc, Instructions);
684 case Mips::LoadAddr32Imm:
685 return expandLoadAddressImm(Inst, IDLoc, Instructions);
686 case Mips::LoadAddr32Reg:
687 return expandLoadAddressReg(Inst, IDLoc, Instructions);
688 }
Jack Carter30a59822012-10-04 04:03:53 +0000689}
Jack Carter92995f12012-10-06 00:53:28 +0000690
Jack Carter30a59822012-10-04 04:03:53 +0000691void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000692 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000693 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000694 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000695 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000696 const MCOperand &RegOp = Inst.getOperand(0);
697 assert(RegOp.isReg() && "expected register operand kind");
698
699 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000700 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000701 if (0 <= ImmValue && ImmValue <= 65535) {
702 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000703 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000704 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000705 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000706 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000707 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000708 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000709 } else if (ImmValue < 0 && ImmValue >= -32768) {
710 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000711 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000712 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000713 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000714 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000715 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000716 Instructions.push_back(tmpInst);
717 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000718 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000719 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000720 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000721 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000722 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
723 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000724 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000725 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000726 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000727 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
728 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
729 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
730 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000731 Instructions.push_back(tmpInst);
732 }
733}
Jack Carter92995f12012-10-06 00:53:28 +0000734
Vladimir Medic4c299852013-11-06 11:27:05 +0000735void
736MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
737 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000738 MCInst tmpInst;
739 const MCOperand &ImmOp = Inst.getOperand(2);
740 assert(ImmOp.isImm() && "expected immediate operand kind");
741 const MCOperand &SrcRegOp = Inst.getOperand(1);
742 assert(SrcRegOp.isReg() && "expected register operand kind");
743 const MCOperand &DstRegOp = Inst.getOperand(0);
744 assert(DstRegOp.isReg() && "expected register operand kind");
745 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000746 if (-32768 <= ImmValue && ImmValue <= 65535) {
747 // For -32768 <= j <= 65535.
748 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000749 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000750 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
751 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
752 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
753 Instructions.push_back(tmpInst);
754 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000755 // For any other value of j that is representable as a 32-bit integer.
756 // la d,j(s) => lui d,hi16(j)
757 // ori d,d,lo16(j)
758 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000759 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000760 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
761 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
762 Instructions.push_back(tmpInst);
763 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000764 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000765 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
766 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
767 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
768 Instructions.push_back(tmpInst);
769 tmpInst.clear();
770 tmpInst.setOpcode(Mips::ADDu);
771 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
772 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
773 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
774 Instructions.push_back(tmpInst);
775 }
776}
777
Vladimir Medic4c299852013-11-06 11:27:05 +0000778void
779MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
780 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000781 MCInst tmpInst;
782 const MCOperand &ImmOp = Inst.getOperand(1);
783 assert(ImmOp.isImm() && "expected immediate operand kind");
784 const MCOperand &RegOp = Inst.getOperand(0);
785 assert(RegOp.isReg() && "expected register operand kind");
786 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000787 if (-32768 <= ImmValue && ImmValue <= 65535) {
788 // For -32768 <= j <= 65535.
789 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000790 tmpInst.setOpcode(Mips::ADDiu);
791 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000792 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000793 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
794 Instructions.push_back(tmpInst);
795 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000796 // For any other value of j that is representable as a 32-bit integer.
797 // la d,j => lui d,hi16(j)
798 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000799 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000800 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
801 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
802 Instructions.push_back(tmpInst);
803 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000804 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000805 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
806 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
807 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
808 Instructions.push_back(tmpInst);
809 }
810}
811
Jack Carter9e65aa32013-03-22 00:05:30 +0000812void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000813 SmallVectorImpl<MCInst> &Instructions,
814 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000815 const MCSymbolRefExpr *SR;
816 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000817 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000818 const MCExpr *ExprOffset;
819 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000820 unsigned AtRegNum = getReg(
821 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000822 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000823 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
824 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000825 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000826 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
827 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000828 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000829 if (isImmOpnd) {
830 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
831 ImmOffset = Inst.getOperand(2).getImm();
832 LoOffset = ImmOffset & 0x0000ffff;
833 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000834 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000835 if (LoOffset & 0x8000)
836 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000837 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000838 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000839 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000840 TempInst.setLoc(IDLoc);
841 // 1st instruction in expansion is LUi. For load instruction we can use
842 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000843 // but for stores we must use $at.
844 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000845 TempInst.setOpcode(Mips::LUi);
846 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
847 if (isImmOpnd)
848 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
849 else {
850 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000851 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000852 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
853 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
854 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000855 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000856 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000857 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000858 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000859 }
860 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000861 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000862 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000863 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000864 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000865 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000866 TempInst.setOpcode(Mips::ADDu);
867 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
868 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
869 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
870 Instructions.push_back(TempInst);
871 TempInst.clear();
Jack Carterb5cf5902013-04-17 00:18:04 +0000872 // And finaly, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000873 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000874 TempInst.setOpcode(Inst.getOpcode());
875 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
876 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
877 if (isImmOpnd)
878 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
879 else {
880 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000881 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
882 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
883 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000884 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000885 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000886 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000887 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000888 }
889 }
890 Instructions.push_back(TempInst);
891 TempInst.clear();
892}
893
Vladimir Medic4c299852013-11-06 11:27:05 +0000894bool MipsAsmParser::MatchAndEmitInstruction(
895 SMLoc IDLoc, unsigned &Opcode,
896 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
897 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000898 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000899 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000900 unsigned MatchResult =
901 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000902
903 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000904 default:
905 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000906 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000908 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000909 for (unsigned i = 0; i < Instructions.size(); i++)
Jack Carter9e65aa32013-03-22 00:05:30 +0000910 Out.EmitInstruction(Instructions[i]);
Jack Carterb4dbc172012-09-05 23:34:03 +0000911 return false;
912 }
913 case Match_MissingFeature:
914 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
915 return true;
916 case Match_InvalidOperand: {
917 SMLoc ErrorLoc = IDLoc;
918 if (ErrorInfo != ~0U) {
919 if (ErrorInfo >= Operands.size())
920 return Error(IDLoc, "too few operands for instruction");
921
Vladimir Medic4c299852013-11-06 11:27:05 +0000922 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000923 if (ErrorLoc == SMLoc())
924 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000925 }
926
927 return Error(ErrorLoc, "invalid operand for instruction");
928 }
929 case Match_MnemonicFail:
930 return Error(IDLoc, "invalid instruction");
931 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000932 return true;
933}
934
Jack Carter1ac53222013-02-20 23:11:17 +0000935int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000936 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +0000937
938 if (Name == "at")
939 return getATReg();
940
Vladimir Medic4c299852013-11-06 11:27:05 +0000941 CC = StringSwitch<unsigned>(Name)
942 .Case("zero", 0)
943 .Case("a0", 4)
944 .Case("a1", 5)
945 .Case("a2", 6)
946 .Case("a3", 7)
947 .Case("v0", 2)
948 .Case("v1", 3)
949 .Case("s0", 16)
950 .Case("s1", 17)
951 .Case("s2", 18)
952 .Case("s3", 19)
953 .Case("s4", 20)
954 .Case("s5", 21)
955 .Case("s6", 22)
956 .Case("s7", 23)
957 .Case("k0", 26)
958 .Case("k1", 27)
959 .Case("sp", 29)
960 .Case("fp", 30)
961 .Case("gp", 28)
962 .Case("ra", 31)
963 .Case("t0", 8)
964 .Case("t1", 9)
965 .Case("t2", 10)
966 .Case("t3", 11)
967 .Case("t4", 12)
968 .Case("t5", 13)
969 .Case("t6", 14)
970 .Case("t7", 15)
971 .Case("t8", 24)
972 .Case("t9", 25)
973 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000974
Jack Carterd0bd6422013-04-18 00:41:53 +0000975 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000976 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
977 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000978 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000979 CC += 4;
980
981 if (CC == -1 && isMips64())
982 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +0000983 .Case("a4", 8)
984 .Case("a5", 9)
985 .Case("a6", 10)
986 .Case("a7", 11)
987 .Case("kt0", 26)
988 .Case("kt1", 27)
989 .Case("s8", 30)
990 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000991
992 return CC;
993}
Jack Carterd0bd6422013-04-18 00:41:53 +0000994
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000995int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000996
Jack Cartera63b16a2012-09-07 00:23:42 +0000997 if (Name[0] == 'f') {
998 StringRef NumString = Name.substr(1);
999 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001000 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001001 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001002 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001003 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001004 return IntVal;
1005 }
1006 return -1;
1007}
Jack Cartera63b16a2012-09-07 00:23:42 +00001008
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001009int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1010
1011 if (Name.startswith("fcc")) {
1012 StringRef NumString = Name.substr(3);
1013 unsigned IntVal;
1014 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001015 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001016 if (IntVal > 7) // There are only 8 fcc registers.
1017 return -1;
1018 return IntVal;
1019 }
1020 return -1;
1021}
1022
1023int MipsAsmParser::matchACRegisterName(StringRef Name) {
1024
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001025 if (Name.startswith("ac")) {
1026 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001027 unsigned IntVal;
1028 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001029 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001030 if (IntVal > 3) // There are only 3 acc registers.
1031 return -1;
1032 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001033 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001034 return -1;
1035}
Jack Carterd0bd6422013-04-18 00:41:53 +00001036
Jack Carter5dc8ac92013-09-25 23:50:44 +00001037int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1038 unsigned IntVal;
1039
1040 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1041 return -1;
1042
1043 if (IntVal > 31)
1044 return -1;
1045
1046 return IntVal;
1047}
1048
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001049int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1050 int CC;
1051
1052 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001053 .Case("msair", 0)
1054 .Case("msacsr", 1)
1055 .Case("msaaccess", 2)
1056 .Case("msasave", 3)
1057 .Case("msamodify", 4)
1058 .Case("msarequest", 5)
1059 .Case("msamap", 6)
1060 .Case("msaunmap", 7)
1061 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001062
1063 return CC;
1064}
1065
Vladimir Medic8cd17102013-06-20 11:21:49 +00001066int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1067
Vladimir Medic8cd17102013-06-20 11:21:49 +00001068 int CC;
1069 CC = matchCPURegisterName(Name);
1070 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001071 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1072 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001073 CC = matchFPURegisterName(Name);
Vladimir Medic4c299852013-11-06 11:27:05 +00001074 // TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001075 if (CC != -1)
1076 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1077 : Mips::FGR32RegClassID);
1078 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001079}
1080
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001081int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001082
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001083 switch (RegKind) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001084 case MipsOperand::Kind_GPR32:
1085 return Mips::GPR32RegClassID;
1086 case MipsOperand::Kind_GPR64:
1087 return Mips::GPR64RegClassID;
1088 case MipsOperand::Kind_HWRegs:
1089 return Mips::HWRegsRegClassID;
1090 case MipsOperand::Kind_FGR32Regs:
1091 return Mips::FGR32RegClassID;
1092 case MipsOperand::Kind_FGRH32Regs:
1093 return Mips::FGRH32RegClassID;
1094 case MipsOperand::Kind_FGR64Regs:
1095 return Mips::FGR64RegClassID;
1096 case MipsOperand::Kind_AFGR64Regs:
1097 return Mips::AFGR64RegClassID;
1098 case MipsOperand::Kind_CCRRegs:
1099 return Mips::CCRRegClassID;
1100 case MipsOperand::Kind_ACC64DSP:
1101 return Mips::ACC64DSPRegClassID;
1102 case MipsOperand::Kind_FCCRegs:
1103 return Mips::FCCRegClassID;
1104 case MipsOperand::Kind_MSA128BRegs:
1105 return Mips::MSA128BRegClassID;
1106 case MipsOperand::Kind_MSA128HRegs:
1107 return Mips::MSA128HRegClassID;
1108 case MipsOperand::Kind_MSA128WRegs:
1109 return Mips::MSA128WRegClassID;
1110 case MipsOperand::Kind_MSA128DRegs:
1111 return Mips::MSA128DRegClassID;
1112 case MipsOperand::Kind_MSA128CtrlRegs:
1113 return Mips::MSACtrlRegClassID;
1114 default:
1115 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001116 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001117}
Jack Carterb4dbc172012-09-05 23:34:03 +00001118
Jack Carter0b744b32012-10-04 02:29:46 +00001119bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1120 if (Reg > 31)
1121 return false;
1122
1123 aTReg = Reg;
1124 return true;
1125}
1126
Vladimir Medic4c299852013-11-06 11:27:05 +00001127int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
Jack Carter0b744b32012-10-04 02:29:46 +00001128
Jack Carterd0bd6422013-04-18 00:41:53 +00001129unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001130 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001131}
1132
Jack Carter873c7242013-01-12 01:03:14 +00001133int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001134 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001135 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001136 return -1;
1137
Jack Carter873c7242013-01-12 01:03:14 +00001138 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001139}
1140
Jack Carter873c7242013-01-12 01:03:14 +00001141int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001142 const AsmToken &Tok = Parser.getTok();
1143 int RegNum = -1;
1144
1145 if (Tok.is(AsmToken::Identifier)) {
1146 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001147 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001148 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001149 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001150 is64BitReg ? Mips::GPR64RegClassID
1151 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001152 return RegNum;
1153}
1154
Jack Carterd0bd6422013-04-18 00:41:53 +00001155bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001156 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001157
1158 SMLoc S = Parser.getTok().getLoc();
1159 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001160
Jack Carter873c7242013-01-12 01:03:14 +00001161 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001162 if (RegNo == -1)
1163 return true;
1164
Vladimir Medic4c299852013-11-06 11:27:05 +00001165 Operands.push_back(
1166 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001167 Parser.Lex(); // Eat register token.
1168 return false;
1169}
1170
Vladimir Medic4c299852013-11-06 11:27:05 +00001171bool
1172MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1173 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001174 // Check if the current operand has a custom associated parser, if so, try to
1175 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001176 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1177 if (ResTy == MatchOperand_Success)
1178 return false;
1179 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1180 // there was a match, but an error occurred, in which case, just return that
1181 // the operand parsing failed.
1182 if (ResTy == MatchOperand_ParseFail)
1183 return true;
1184
1185 switch (getLexer().getKind()) {
1186 default:
1187 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1188 return true;
1189 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001190 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001191 SMLoc S = Parser.getTok().getLoc();
1192 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001193 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001194 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001195 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001196 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001197 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001198 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001199 if (getLexer().isNot(AsmToken::Dollar))
1200 return true;
1201
Jack Carterd0bd6422013-04-18 00:41:53 +00001202 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001203 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001204 return true;
1205
1206 if (!getLexer().is(AsmToken::RParen))
1207 return true;
1208
1209 S = Parser.getTok().getLoc();
1210 Operands.push_back(MipsOperand::CreateToken(")", S));
1211 Parser.Lex();
1212 }
1213 return false;
1214 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001215 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001216 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001217 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001218 return true;
1219
Jack Carter873c7242013-01-12 01:03:14 +00001220 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001221 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001222 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001223 const MCExpr *Res =
1224 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001225
1226 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1227 return false;
1228 }
1229 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001230 // For instruction aliases like "bc1f $Label" dedicated parser will
1231 // eat the '$' sign before failing. So in order to look for appropriate
1232 // label we must check first if we have already consumed '$'.
1233 if (hasConsumedDollar) {
1234 hasConsumedDollar = false;
1235 SMLoc S = Parser.getTok().getLoc();
1236 StringRef Identifier;
1237 if (Parser.parseIdentifier(Identifier))
1238 return true;
1239 SMLoc E =
1240 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1241 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1242 // Create a symbol reference.
1243 const MCExpr *Res =
1244 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1245
1246 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1247 return false;
1248 }
Jack Carterd76b2372013-03-21 21:44:16 +00001249 // Look for the existing symbol, we should check if
Jack Carterd0bd6422013-04-18 00:41:53 +00001250 // we need to assigne the propper RegisterKind.
1251 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1252 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001253 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001254 case AsmToken::LParen:
1255 case AsmToken::Minus:
1256 case AsmToken::Plus:
1257 case AsmToken::Integer:
1258 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001259 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001260 const MCExpr *IdVal;
1261 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001262 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001263 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001264 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001265 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1266 return false;
1267 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001268 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001269 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001270 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001271 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001272 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001273 return true;
1274
Jack Carter873c7242013-01-12 01:03:14 +00001275 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1276
Jack Carterdc1e35d2012-09-06 20:00:02 +00001277 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1278 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001279 } // case AsmToken::Percent
1280 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001281 return true;
1282}
1283
Vladimir Medic4c299852013-11-06 11:27:05 +00001284const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001285 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001286 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001287 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001288 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001289 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001290 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001291 short Val = MCE->getValue();
1292 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001293 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001294 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001295 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001296 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001297 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001298 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001299 if (LoSign)
1300 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001301 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001302 } else {
1303 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001304 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001305 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001306 }
1307
Jack Carterb5cf5902013-04-17 00:18:04 +00001308 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001309 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001310 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001311 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001312 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001313 return Res;
1314 }
1315
1316 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001317 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1318 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001319 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1320 return Res;
1321 }
1322
1323 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001324 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1325 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1326 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001327 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001328 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001329 return Expr;
1330}
1331
1332bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1333
1334 switch (Expr->getKind()) {
1335 case MCExpr::Constant:
1336 return true;
1337 case MCExpr::SymbolRef:
1338 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1339 case MCExpr::Binary:
1340 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1341 if (!isEvaluated(BE->getLHS()))
1342 return false;
1343 return isEvaluated(BE->getRHS());
1344 }
1345 case MCExpr::Unary:
1346 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1347 default:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001348 return false;
1349 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001350 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001351}
Jack Carterd0bd6422013-04-18 00:41:53 +00001352
Jack Carterb5cf5902013-04-17 00:18:04 +00001353bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001354 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001355 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001356 if (Tok.isNot(AsmToken::Identifier))
1357 return true;
1358
1359 std::string Str = Tok.getIdentifier().str();
1360
Jack Carterd0bd6422013-04-18 00:41:53 +00001361 Parser.Lex(); // Eat the identifier.
1362 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001363 const MCExpr *IdVal;
1364 SMLoc EndLoc;
1365
1366 if (getLexer().getKind() == AsmToken::LParen) {
1367 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001368 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001369 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001370 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001371 const AsmToken &nextTok = Parser.getTok();
1372 if (nextTok.isNot(AsmToken::Identifier))
1373 return true;
1374 Str += "(%";
1375 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001376 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001377 if (getLexer().getKind() != AsmToken::LParen)
1378 return true;
1379 } else
1380 break;
1381 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001382 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001383 return true;
1384
1385 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001386 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001387
1388 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001389 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001390
Jack Carterd0bd6422013-04-18 00:41:53 +00001391 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001392 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001393}
1394
Jack Carterb4dbc172012-09-05 23:34:03 +00001395bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1396 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001397 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001398 RegNo = tryParseRegister(isMips64());
1399 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001400 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001401}
1402
Jack Carterb5cf5902013-04-17 00:18:04 +00001403bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001404 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001405 bool Result = true;
1406
1407 while (getLexer().getKind() == AsmToken::LParen)
1408 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001409
Jack Carterd0bd6422013-04-18 00:41:53 +00001410 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001411 default:
1412 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001413 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001414 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001415 case AsmToken::Integer:
1416 case AsmToken::Minus:
1417 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001418 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001419 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001420 else
1421 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001422 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001423 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001424 break;
Jack Carter873c7242013-01-12 01:03:14 +00001425 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001426 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001427 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001428 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001429}
1430
Jack Carterb4dbc172012-09-05 23:34:03 +00001431MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001432 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001433
1434 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001435 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001436 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001437 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001438 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001439 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001440
Jack Carterb5cf5902013-04-17 00:18:04 +00001441 if (getLexer().getKind() == AsmToken::LParen) {
1442 Parser.Lex();
1443 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001444 }
1445
Jack Carterb5cf5902013-04-17 00:18:04 +00001446 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001447 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001448 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001449
Jack Carterd0bd6422013-04-18 00:41:53 +00001450 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001451 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001452 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001453 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001454 SMLoc E =
1455 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001456 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1457 return MatchOperand_Success;
1458 }
1459 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001460 SMLoc E =
1461 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001462
Jack Carterd0bd6422013-04-18 00:41:53 +00001463 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001464 Operands.push_back(MipsOperand::CreateMem(
1465 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001466 return MatchOperand_Success;
1467 }
1468 Error(Parser.getTok().getLoc(), "'(' expected");
1469 return MatchOperand_ParseFail;
1470 }
1471
Jack Carterd0bd6422013-04-18 00:41:53 +00001472 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001473 }
1474
Vladimir Medic4c299852013-11-06 11:27:05 +00001475 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1476 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001477 if (Res != MatchOperand_Success)
1478 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001479
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001480 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001481 Error(Parser.getTok().getLoc(), "')' expected");
1482 return MatchOperand_ParseFail;
1483 }
1484
Jack Carter873c7242013-01-12 01:03:14 +00001485 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1486
Jack Carterd0bd6422013-04-18 00:41:53 +00001487 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001488
1489 if (IdVal == 0)
1490 IdVal = MCConstantExpr::Create(0, getContext());
1491
Jack Carterd0bd6422013-04-18 00:41:53 +00001492 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001493 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001494 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001495 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001496 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001497 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001498 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1499 int64_t Imm;
1500 if (IdVal->EvaluateAsAbsolute(Imm))
1501 IdVal = MCConstantExpr::Create(Imm, getContext());
1502 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1503 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1504 getContext());
1505 }
1506
Jack Carterdc1e35d2012-09-06 20:00:02 +00001507 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1508 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001509 return MatchOperand_Success;
1510}
1511
Vladimir Medic4c299852013-11-06 11:27:05 +00001512bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1513 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001514 // If the first token is not '$' we have an error.
1515 if (Parser.getTok().isNot(AsmToken::Dollar))
1516 return false;
1517
1518 SMLoc S = Parser.getTok().getLoc();
1519 Parser.Lex();
1520 AsmToken::TokenKind TkKind = getLexer().getKind();
1521 int Reg;
1522
1523 if (TkKind == AsmToken::Integer) {
1524 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1525 regKindToRegClass(RegKind));
1526 if (Reg == -1)
1527 return false;
1528 } else if (TkKind == AsmToken::Identifier) {
1529 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1530 return false;
1531 Reg = getReg(regKindToRegClass(RegKind), Reg);
1532 } else {
1533 return false;
1534 }
1535
1536 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1537 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1538 Operands.push_back(Op);
1539 Parser.Lex();
1540 return true;
1541}
1542
1543MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001544MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1545 MipsOperand::RegisterKind RegKind =
1546 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001547
1548 // Parse index register.
1549 if (!parsePtrReg(Operands, RegKind))
1550 return MatchOperand_NoMatch;
1551
1552 // Parse '('.
1553 if (Parser.getTok().isNot(AsmToken::LParen))
1554 return MatchOperand_NoMatch;
1555
1556 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1557 Parser.Lex();
1558
1559 // Parse base register.
1560 if (!parsePtrReg(Operands, RegKind))
1561 return MatchOperand_NoMatch;
1562
1563 // Parse ')'.
1564 if (Parser.getTok().isNot(AsmToken::RParen))
1565 return MatchOperand_NoMatch;
1566
1567 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1568 Parser.Lex();
1569
1570 return MatchOperand_Success;
1571}
1572
Jack Carter873c7242013-01-12 01:03:14 +00001573MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001574MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001575 int RegKind) {
1576 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001577 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001578 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001579 return MatchOperand_Success;
1580 return MatchOperand_NoMatch;
1581 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001582 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001583 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001584 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001585 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001586 if (!hasConsumedDollar) {
1587 Parser.Lex(); // Eat the '$'
1588 hasConsumedDollar = true;
1589 }
1590 if (getLexer().getKind() == AsmToken::Identifier) {
1591 int RegNum = -1;
1592 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001593 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001594 switch (RegKind) {
1595 case MipsOperand::Kind_GPR32:
1596 case MipsOperand::Kind_GPR64:
1597 RegNum = matchCPURegisterName(RegName);
1598 break;
1599 case MipsOperand::Kind_AFGR64Regs:
1600 case MipsOperand::Kind_FGR64Regs:
1601 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001602 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001603 RegNum = matchFPURegisterName(RegName);
1604 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1605 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001606 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1607 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001608 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001609 break;
1610 case MipsOperand::Kind_FCCRegs:
1611 RegNum = matchFCCRegisterName(RegName);
1612 break;
1613 case MipsOperand::Kind_ACC64DSP:
1614 RegNum = matchACRegisterName(RegName);
1615 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001616 default:
1617 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001618 }
1619 // No match found, return _NoMatch to give a chance to other round.
1620 if (RegNum < 0)
1621 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001622
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001623 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1624 if (RegVal == -1)
1625 return MatchOperand_NoMatch;
1626
Vladimir Medic4c299852013-11-06 11:27:05 +00001627 MipsOperand *Op =
1628 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001629 Op->setRegKind(Kind);
1630 Operands.push_back(Op);
1631 hasConsumedDollar = false;
1632 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001633 return MatchOperand_Success;
1634 } else if (getLexer().getKind() == AsmToken::Integer) {
1635 unsigned RegNum = Parser.getTok().getIntVal();
1636 if (Kind == MipsOperand::Kind_HWRegs) {
1637 if (RegNum != 29)
1638 return MatchOperand_NoMatch;
1639 // Only hwreg 29 is supported, found at index 0.
1640 RegNum = 0;
1641 }
1642 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1643 if (Reg == -1)
1644 return MatchOperand_NoMatch;
1645 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1646 Op->setRegKind(Kind);
1647 Operands.push_back(Op);
1648 hasConsumedDollar = false;
1649 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001650 if ((RegKind == MipsOperand::Kind_GPR32) &&
1651 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001652 // Check if it is indexed addressing operand.
1653 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1654 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001655 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001656 return MatchOperand_NoMatch;
1657 if (getLexer().isNot(AsmToken::RParen))
1658 return MatchOperand_NoMatch;
1659 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1660 Parser.Lex();
1661 }
Jack Carter873c7242013-01-12 01:03:14 +00001662 return MatchOperand_Success;
1663 }
1664 return MatchOperand_NoMatch;
1665}
Vladimir Medic64828a12013-07-16 10:07:14 +00001666
Matheus Almeidab74293d2013-10-14 11:49:30 +00001667bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1668 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1669
1670 if (Val < 0)
1671 return false;
1672
1673 switch (Kind) {
1674 default:
1675 return false;
1676 case MipsOperand::Kind_MSA128BRegs:
1677 return Val < 16;
1678 case MipsOperand::Kind_MSA128HRegs:
1679 return Val < 8;
1680 case MipsOperand::Kind_MSA128WRegs:
1681 return Val < 4;
1682 case MipsOperand::Kind_MSA128DRegs:
1683 return Val < 2;
1684 }
1685}
1686
Vladimir Medic8cd17102013-06-20 11:21:49 +00001687MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001688MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001689 int RegKind) {
1690 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1691 SMLoc S = Parser.getTok().getLoc();
1692 std::string RegName;
1693
1694 if (Parser.getTok().isNot(AsmToken::Dollar))
1695 return MatchOperand_NoMatch;
1696
1697 switch (RegKind) {
1698 default:
1699 return MatchOperand_ParseFail;
1700 case MipsOperand::Kind_MSA128BRegs:
1701 case MipsOperand::Kind_MSA128HRegs:
1702 case MipsOperand::Kind_MSA128WRegs:
1703 case MipsOperand::Kind_MSA128DRegs:
1704 break;
1705 }
1706
1707 Parser.Lex(); // Eat the '$'.
1708 if (getLexer().getKind() == AsmToken::Identifier)
1709 RegName = Parser.getTok().getString().lower();
1710 else
1711 return MatchOperand_ParseFail;
1712
1713 int RegNum = matchMSA128RegisterName(RegName);
1714
1715 if (RegNum < 0 || RegNum > 31)
1716 return MatchOperand_ParseFail;
1717
1718 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1719 if (RegVal == -1)
1720 return MatchOperand_ParseFail;
1721
Vladimir Medic4c299852013-11-06 11:27:05 +00001722 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001723 Op->setRegKind(Kind);
1724 Operands.push_back(Op);
1725
1726 Parser.Lex(); // Eat the register identifier.
1727
Matheus Almeidab74293d2013-10-14 11:49:30 +00001728 // MSA registers may be suffixed with an index in the form of:
1729 // 1) Immediate expression.
1730 // 2) General Purpose Register.
1731 // Examples:
1732 // 1) copy_s.b $29,$w0[0]
1733 // 2) sld.b $w0,$w1[$1]
1734
1735 if (Parser.getTok().isNot(AsmToken::LBrac))
1736 return MatchOperand_Success;
1737
1738 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1739
1740 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1741 Parser.Lex(); // Parse the '[' token.
1742
1743 if (Parser.getTok().is(AsmToken::Dollar)) {
1744 // This must be a GPR.
1745 MipsOperand *RegOp;
1746 SMLoc VIdx = Parser.getTok().getLoc();
1747 Parser.Lex(); // Parse the '$' token.
1748
1749 // GPR have aliases and we must account for that. Example: $30 == $fp
1750 if (getLexer().getKind() == AsmToken::Integer) {
1751 unsigned RegNum = Parser.getTok().getIntVal();
1752 int Reg = matchRegisterByNumber(
1753 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1754 if (Reg == -1) {
1755 Error(VIdx, "invalid general purpose register");
1756 return MatchOperand_ParseFail;
1757 }
1758
1759 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1760 } else if (getLexer().getKind() == AsmToken::Identifier) {
1761 int RegNum = -1;
1762 std::string RegName = Parser.getTok().getString().lower();
1763
1764 RegNum = matchCPURegisterName(RegName);
1765 if (RegNum == -1) {
1766 Error(VIdx, "general purpose register expected");
1767 return MatchOperand_ParseFail;
1768 }
1769 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1770 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1771 } else
1772 return MatchOperand_ParseFail;
1773
1774 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1775 Operands.push_back(RegOp);
1776 Parser.Lex(); // Eat the register identifier.
1777
1778 if (Parser.getTok().isNot(AsmToken::RBrac))
1779 return MatchOperand_ParseFail;
1780
1781 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1782 Parser.Lex(); // Parse the ']' token.
1783
1784 return MatchOperand_Success;
1785 }
1786
1787 // The index must be a constant expression then.
1788 SMLoc VIdx = Parser.getTok().getLoc();
1789 const MCExpr *ImmVal;
1790
1791 if (getParser().parseExpression(ImmVal))
1792 return MatchOperand_ParseFail;
1793
1794 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1795 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1796 Error(VIdx, "invalid immediate value");
1797 return MatchOperand_ParseFail;
1798 }
1799
1800 SMLoc E = Parser.getTok().getEndLoc();
1801
1802 if (Parser.getTok().isNot(AsmToken::RBrac))
1803 return MatchOperand_ParseFail;
1804
Vladimir Medic4c299852013-11-06 11:27:05 +00001805 bool insve =
1806 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1807 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001808
1809 // The second vector index of insve instructions is always 0.
1810 if (insve && Operands.size() > 6) {
1811 if (expr->getValue() != 0) {
1812 Error(VIdx, "immediate value must be 0");
1813 return MatchOperand_ParseFail;
1814 }
1815 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1816 } else
1817 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1818
1819 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1820
1821 Parser.Lex(); // Parse the ']' token.
1822
Jack Carter5dc8ac92013-09-25 23:50:44 +00001823 return MatchOperand_Success;
1824}
1825
1826MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001827MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1828 int RegKind) {
1829 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1830
1831 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1832 return MatchOperand_NoMatch;
1833
1834 if (Parser.getTok().isNot(AsmToken::Dollar))
1835 return MatchOperand_ParseFail;
1836
1837 SMLoc S = Parser.getTok().getLoc();
1838
1839 Parser.Lex(); // Eat the '$' symbol.
1840
1841 int RegNum = -1;
1842 if (getLexer().getKind() == AsmToken::Identifier)
1843 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1844 else if (getLexer().getKind() == AsmToken::Integer)
1845 RegNum = Parser.getTok().getIntVal();
1846 else
1847 return MatchOperand_ParseFail;
1848
1849 if (RegNum < 0 || RegNum > 7)
1850 return MatchOperand_ParseFail;
1851
1852 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1853 if (RegVal == -1)
1854 return MatchOperand_ParseFail;
1855
Vladimir Medic4c299852013-11-06 11:27:05 +00001856 MipsOperand *RegOp =
1857 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001858 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1859 Operands.push_back(RegOp);
1860 Parser.Lex(); // Eat the register identifier.
1861
1862 return MatchOperand_Success;
1863}
1864
1865MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001866MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001867
1868 if (!isMips64())
1869 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001870 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001871}
1872
1873MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001874MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1875 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001876}
Jack Carter873c7242013-01-12 01:03:14 +00001877
Vladimir Medic4c299852013-11-06 11:27:05 +00001878MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1879 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001880
1881 if (isFP64())
1882 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001883 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001884}
1885
1886MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001887MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001888 if (!isFP64())
1889 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001890 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001891}
1892
1893MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001894MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1895 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1896}
1897
1898MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1899 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1900 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001901}
1902
Vladimir Medic643b3982013-07-30 10:12:14 +00001903MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001904MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1905 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001906}
1907
1908MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001909MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1910 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001911}
1912
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001913MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001914MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001915 // If the first token is not '$' we have an error.
1916 if (Parser.getTok().isNot(AsmToken::Dollar))
1917 return MatchOperand_NoMatch;
1918
1919 SMLoc S = Parser.getTok().getLoc();
1920 Parser.Lex(); // Eat the '$'
1921
1922 const AsmToken &Tok = Parser.getTok(); // Get next token.
1923
1924 if (Tok.isNot(AsmToken::Identifier))
1925 return MatchOperand_NoMatch;
1926
1927 if (!Tok.getIdentifier().startswith("ac"))
1928 return MatchOperand_NoMatch;
1929
1930 StringRef NumString = Tok.getIdentifier().substr(2);
1931
1932 unsigned IntVal;
1933 if (NumString.getAsInteger(10, IntVal))
1934 return MatchOperand_NoMatch;
1935
1936 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1937
1938 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1939 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1940 Operands.push_back(Op);
1941
1942 Parser.Lex(); // Eat the register number.
1943 return MatchOperand_Success;
1944}
1945
1946MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001947MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001948 // If the first token is not '$' we have an error.
1949 if (Parser.getTok().isNot(AsmToken::Dollar))
1950 return MatchOperand_NoMatch;
1951
1952 SMLoc S = Parser.getTok().getLoc();
1953 Parser.Lex(); // Eat the '$'
1954
1955 const AsmToken &Tok = Parser.getTok(); // Get next token.
1956
1957 if (Tok.isNot(AsmToken::Identifier))
1958 return MatchOperand_NoMatch;
1959
1960 if (!Tok.getIdentifier().startswith("ac"))
1961 return MatchOperand_NoMatch;
1962
1963 StringRef NumString = Tok.getIdentifier().substr(2);
1964
1965 unsigned IntVal;
1966 if (NumString.getAsInteger(10, IntVal))
1967 return MatchOperand_NoMatch;
1968
1969 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1970
1971 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1972 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1973 Operands.push_back(Op);
1974
1975 Parser.Lex(); // Eat the register number.
1976 return MatchOperand_Success;
1977}
1978
Vladimir Medic05bcde62013-09-16 10:29:42 +00001979MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001980MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00001981 // If the first token is not '$' we have an error.
1982 if (Parser.getTok().isNot(AsmToken::Dollar))
1983 return MatchOperand_NoMatch;
1984
1985 SMLoc S = Parser.getTok().getLoc();
1986 Parser.Lex(); // Eat the '$'
1987
1988 const AsmToken &Tok = Parser.getTok(); // Get next token.
1989
1990 if (Tok.isNot(AsmToken::Integer))
1991 return MatchOperand_NoMatch;
1992
1993 unsigned IntVal = Tok.getIntVal();
1994
1995 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1996
1997 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1998 Op->setRegKind(MipsOperand::Kind_COP2);
1999 Operands.push_back(Op);
2000
2001 Parser.Lex(); // Eat the register number.
2002 return MatchOperand_Success;
2003}
2004
Vladimir Medic4c299852013-11-06 11:27:05 +00002005MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2006 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2007 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002008}
2009
Vladimir Medic4c299852013-11-06 11:27:05 +00002010MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2011 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2012 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002013}
2014
Vladimir Medic4c299852013-11-06 11:27:05 +00002015MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2016 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2017 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002018}
2019
Vladimir Medic4c299852013-11-06 11:27:05 +00002020MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2021 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2022 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002023}
2024
Vladimir Medic4c299852013-11-06 11:27:05 +00002025MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2026 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2027 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002028}
2029
Jack Carterd0bd6422013-04-18 00:41:53 +00002030bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002031 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002032
2033 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2034 if (Sym) {
2035 SMLoc S = Parser.getTok().getLoc();
2036 const MCExpr *Expr;
2037 if (Sym->isVariable())
2038 Expr = Sym->getVariableValue();
2039 else
2040 return false;
2041 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002042 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2043 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002044 const StringRef DefSymbol = Ref->getSymbol().getName();
2045 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002046 int RegNum = -1;
2047 APInt IntVal(32, -1);
2048 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2049 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002050 isMips64() ? Mips::GPR64RegClassID
2051 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002052 else {
2053 // Lookup for the register with the corresponding name.
2054 switch (Kind) {
2055 case MipsOperand::Kind_AFGR64Regs:
2056 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002057 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002058 break;
2059 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002060 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002061 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002062 case MipsOperand::Kind_GPR64:
2063 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002064 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002065 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002066 break;
2067 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002068 if (RegNum > -1)
2069 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002070 }
Jack Carterd76b2372013-03-21 21:44:16 +00002071 if (RegNum > -1) {
2072 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002073 MipsOperand *op =
2074 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002075 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002076 Operands.push_back(op);
2077 return true;
2078 }
2079 }
2080 } else if (Expr->getKind() == MCExpr::Constant) {
2081 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002082 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2083 MipsOperand *op =
2084 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002085 Operands.push_back(op);
2086 return true;
2087 }
2088 }
2089 return false;
2090}
Jack Carterd0bd6422013-04-18 00:41:53 +00002091
Jack Carter873c7242013-01-12 01:03:14 +00002092MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002093MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2094 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002095}
2096
2097MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002098MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2099 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002100}
2101
Vladimir Medic2b953d02013-10-01 09:48:56 +00002102MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002103MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002104 const MCExpr *IdVal;
2105 // If the first token is '$' we may have register operand.
2106 if (Parser.getTok().is(AsmToken::Dollar))
2107 return MatchOperand_NoMatch;
2108 SMLoc S = Parser.getTok().getLoc();
2109 if (getParser().parseExpression(IdVal))
2110 return MatchOperand_ParseFail;
2111 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002112 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002113 int64_t Val = MCE->getValue();
2114 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2115 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002116 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002117 return MatchOperand_Success;
2118}
2119
Matheus Almeida779c5932013-11-18 12:32:49 +00002120MipsAsmParser::OperandMatchResultTy
2121MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2122 switch (getLexer().getKind()) {
2123 default:
2124 return MatchOperand_NoMatch;
2125 case AsmToken::LParen:
2126 case AsmToken::Plus:
2127 case AsmToken::Minus:
2128 case AsmToken::Integer:
2129 break;
2130 }
2131
2132 const MCExpr *Expr;
2133 SMLoc S = Parser.getTok().getLoc();
2134
2135 if (getParser().parseExpression(Expr))
2136 return MatchOperand_ParseFail;
2137
2138 int64_t Val;
2139 if (!Expr->EvaluateAsAbsolute(Val)) {
2140 Error(S, "expected immediate value");
2141 return MatchOperand_ParseFail;
2142 }
2143
2144 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2145 // and because the CPU always adds one to the immediate field, the allowed
2146 // range becomes 1..4. We'll only check the range here and will deal
2147 // with the addition/subtraction when actually decoding/encoding
2148 // the instruction.
2149 if (Val < 1 || Val > 4) {
2150 Error(S, "immediate not in range (1..4)");
2151 return MatchOperand_ParseFail;
2152 }
2153
Jack Carter3b2c96e2014-01-22 23:31:38 +00002154 Operands.push_back(
2155 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002156 return MatchOperand_Success;
2157}
2158
Jack Carterdc1e35d2012-09-06 20:00:02 +00002159MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2160
Vladimir Medic4c299852013-11-06 11:27:05 +00002161 MCSymbolRefExpr::VariantKind VK =
2162 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2163 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2164 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2165 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2166 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2167 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2168 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2169 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2170 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2171 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2172 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2173 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2174 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2175 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2176 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2177 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2178 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2179 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2180 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002181
2182 return VK;
2183}
Jack Cartera63b16a2012-09-07 00:23:42 +00002184
Vladimir Medic4c299852013-11-06 11:27:05 +00002185bool MipsAsmParser::ParseInstruction(
2186 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2187 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002188 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002189 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002190 Parser.eatToEndOfStatement();
2191 return Error(NameLoc, "Unknown instruction");
2192 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002193 // First operand in MCInst is instruction mnemonic.
2194 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002195
2196 // Read the remaining operands.
2197 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2198 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002199 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002200 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002201 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002202 return Error(Loc, "unexpected token in argument list");
2203 }
2204
Jack Carterd0bd6422013-04-18 00:41:53 +00002205 while (getLexer().is(AsmToken::Comma)) {
2206 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002207 // Parse and remember the operand.
2208 if (ParseOperand(Operands, Name)) {
2209 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002210 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002211 return Error(Loc, "unexpected token in argument list");
2212 }
2213 }
2214 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002215 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2216 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002217 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002218 return Error(Loc, "unexpected token in argument list");
2219 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002220 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002221 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002222}
2223
Jack Carter0b744b32012-10-04 02:29:46 +00002224bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002225 SMLoc Loc = getLexer().getLoc();
2226 Parser.eatToEndOfStatement();
2227 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002228}
2229
2230bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002231 // Line should look like: ".set noat".
2232 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002233 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002234 // eat noat
2235 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002236 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002237 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2238 reportParseError("unexpected token in statement");
2239 return false;
2240 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002241 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002242 return false;
2243}
Jack Carterd0bd6422013-04-18 00:41:53 +00002244
Jack Carter0b744b32012-10-04 02:29:46 +00002245bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002246 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002247 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002248 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002249 getParser().Lex();
2250 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002251 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002252 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002253 return false;
2254 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002255 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002256 if (getLexer().isNot(AsmToken::Dollar)) {
2257 reportParseError("unexpected token in statement");
2258 return false;
2259 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002260 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002261 const AsmToken &Reg = Parser.getTok();
2262 if (Reg.is(AsmToken::Identifier)) {
2263 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2264 } else if (Reg.is(AsmToken::Integer)) {
2265 AtRegNo = Reg.getIntVal();
2266 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002267 reportParseError("unexpected token in statement");
2268 return false;
2269 }
Jack Carter1ac53222013-02-20 23:11:17 +00002270
Jack Carterd0bd6422013-04-18 00:41:53 +00002271 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002272 reportParseError("unexpected token in statement");
2273 return false;
2274 }
2275
2276 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002277 reportParseError("unexpected token in statement");
2278 return false;
2279 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002280 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002281
2282 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2283 reportParseError("unexpected token in statement");
2284 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002285 }
2286 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002287 return false;
2288 } else {
2289 reportParseError("unexpected token in statement");
2290 return false;
2291 }
2292}
2293
2294bool MipsAsmParser::parseSetReorderDirective() {
2295 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002296 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002297 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2298 reportParseError("unexpected token in statement");
2299 return false;
2300 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002301 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002302 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002303 return false;
2304}
2305
2306bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002307 Parser.Lex();
2308 // If this is not the end of the statement, report an error.
2309 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2310 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002311 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002312 }
2313 Options.setNoreorder();
2314 Parser.Lex(); // Consume the EndOfStatement.
2315 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002316}
2317
2318bool MipsAsmParser::parseSetMacroDirective() {
2319 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002320 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002321 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2322 reportParseError("unexpected token in statement");
2323 return false;
2324 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002325 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002326 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002327 return false;
2328}
2329
2330bool MipsAsmParser::parseSetNoMacroDirective() {
2331 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002332 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002333 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2334 reportParseError("`noreorder' must be set before `nomacro'");
2335 return false;
2336 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002337 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002338 reportParseError("`noreorder' must be set before `nomacro'");
2339 return false;
2340 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002341 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002342 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002343 return false;
2344}
Jack Carterd76b2372013-03-21 21:44:16 +00002345
Jack Carter39536722014-01-22 23:08:42 +00002346bool MipsAsmParser::parseSetMips16Directive() {
2347 Parser.Lex();
2348 // If this is not the end of the statement, report an error.
2349 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2350 reportParseError("unexpected token in statement");
2351 return false;
2352 }
Rafael Espindolae7583752014-01-24 16:13:20 +00002353 getTargetStreamer().emitDirectiveSetMips16();
Jack Carter39536722014-01-22 23:08:42 +00002354 Parser.Lex(); // Consume the EndOfStatement.
2355 return false;
2356}
2357
2358bool MipsAsmParser::parseSetNoMips16Directive() {
2359 Parser.Lex();
2360 // If this is not the end of the statement, report an error.
2361 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2362 reportParseError("unexpected token in statement");
2363 return false;
2364 }
2365 // For now do nothing.
2366 Parser.Lex(); // Consume the EndOfStatement.
2367 return false;
2368}
2369
Jack Carterd76b2372013-03-21 21:44:16 +00002370bool MipsAsmParser::parseSetAssignment() {
2371 StringRef Name;
2372 const MCExpr *Value;
2373
2374 if (Parser.parseIdentifier(Name))
2375 reportParseError("expected identifier after .set");
2376
2377 if (getLexer().isNot(AsmToken::Comma))
2378 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002379 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002380
Jack Carter3b2c96e2014-01-22 23:31:38 +00002381 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002382 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002383
Jack Carterd0bd6422013-04-18 00:41:53 +00002384 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002385 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002386 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002387 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002388 Sym = getContext().GetOrCreateSymbol(Name);
2389 Sym->setVariableValue(Value);
2390
2391 return false;
2392}
Jack Carterd0bd6422013-04-18 00:41:53 +00002393
Jack Carter0b744b32012-10-04 02:29:46 +00002394bool MipsAsmParser::parseDirectiveSet() {
2395
Jack Carterd0bd6422013-04-18 00:41:53 +00002396 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002397 const AsmToken &Tok = Parser.getTok();
2398
2399 if (Tok.getString() == "noat") {
2400 return parseSetNoAtDirective();
2401 } else if (Tok.getString() == "at") {
2402 return parseSetAtDirective();
2403 } else if (Tok.getString() == "reorder") {
2404 return parseSetReorderDirective();
2405 } else if (Tok.getString() == "noreorder") {
2406 return parseSetNoReorderDirective();
2407 } else if (Tok.getString() == "macro") {
2408 return parseSetMacroDirective();
2409 } else if (Tok.getString() == "nomacro") {
2410 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002411 } else if (Tok.getString() == "mips16") {
2412 return parseSetMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002413 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002414 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002415 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002416 getTargetStreamer().emitDirectiveSetNoMicroMips();
2417 Parser.eatToEndOfStatement();
2418 return false;
2419 } else if (Tok.getString() == "micromips") {
2420 getTargetStreamer().emitDirectiveSetMicroMips();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002421 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002422 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002423 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002424 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002425 parseSetAssignment();
2426 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002427 }
Jack Carter07c818d2013-01-25 01:31:34 +00002428
Jack Carter0b744b32012-10-04 02:29:46 +00002429 return true;
2430}
2431
Jack Carter6ef6cc52013-11-19 20:53:28 +00002432bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2433 int64_t Flags = 0;
Saleem Abdulrasoola6505ca2014-01-13 01:15:39 +00002434 if (Parser.parseAbsoluteExpression(Flags)) {
2435 TokError("unexpected token");
2436 return false;
2437 }
Jack Carter6ef6cc52013-11-19 20:53:28 +00002438
2439 getTargetStreamer().emitMipsHackELFFlags(Flags);
2440 return false;
2441}
2442
Jack Carter07c818d2013-01-25 01:31:34 +00002443/// parseDirectiveWord
2444/// ::= .word [ expression (, expression)* ]
2445bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2446 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2447 for (;;) {
2448 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002449 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002450 return true;
2451
2452 getParser().getStreamer().EmitValue(Value, Size);
2453
2454 if (getLexer().is(AsmToken::EndOfStatement))
2455 break;
2456
2457 // FIXME: Improve diagnostic.
2458 if (getLexer().isNot(AsmToken::Comma))
2459 return Error(L, "unexpected token in directive");
2460 Parser.Lex();
2461 }
2462 }
2463
2464 Parser.Lex();
2465 return false;
2466}
2467
Vladimir Medic4c299852013-11-06 11:27:05 +00002468/// parseDirectiveGpWord
2469/// ::= .gpword local_sym
2470bool MipsAsmParser::parseDirectiveGpWord() {
2471 const MCExpr *Value;
2472 // EmitGPRel32Value requires an expression, so we are using base class
2473 // method to evaluate the expression.
2474 if (getParser().parseExpression(Value))
2475 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002476 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002477
Vladimir Medice10c1122013-11-13 13:18:04 +00002478 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002479 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002480 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002481 return false;
2482}
2483
Jack Carter0cd3c192014-01-06 23:27:31 +00002484bool MipsAsmParser::parseDirectiveOption() {
2485 // Get the option token.
2486 AsmToken Tok = Parser.getTok();
2487 // At the moment only identifiers are supported.
2488 if (Tok.isNot(AsmToken::Identifier)) {
2489 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2490 Parser.eatToEndOfStatement();
2491 return false;
2492 }
2493
2494 StringRef Option = Tok.getIdentifier();
2495
2496 if (Option == "pic0") {
2497 getTargetStreamer().emitDirectiveOptionPic0();
2498 Parser.Lex();
2499 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2500 Error(Parser.getTok().getLoc(),
2501 "unexpected token in .option pic0 directive");
2502 Parser.eatToEndOfStatement();
2503 }
2504 return false;
2505 }
2506
2507 // Unknown option.
2508 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2509 Parser.eatToEndOfStatement();
2510 return false;
2511}
2512
Jack Carter0b744b32012-10-04 02:29:46 +00002513bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002514 StringRef IDVal = DirectiveID.getString();
2515
Jack Carterd0bd6422013-04-18 00:41:53 +00002516 if (IDVal == ".ent") {
2517 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002518 Parser.Lex();
2519 return false;
2520 }
2521
Jack Carter07c818d2013-01-25 01:31:34 +00002522 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002523 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002524 Parser.Lex();
2525 return false;
2526 }
2527
Jack Carter07c818d2013-01-25 01:31:34 +00002528 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002529 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002530 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002531 return false;
2532 }
2533
Jack Carter07c818d2013-01-25 01:31:34 +00002534 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002535 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002536 }
2537
Jack Carter07c818d2013-01-25 01:31:34 +00002538 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002539 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002540 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002541 return false;
2542 }
2543
Jack Carter07c818d2013-01-25 01:31:34 +00002544 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002545 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002546 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002547 return false;
2548 }
2549
Jack Carter07c818d2013-01-25 01:31:34 +00002550 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002551 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002552 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002553 return false;
2554 }
2555
Jack Carter07c818d2013-01-25 01:31:34 +00002556 if (IDVal == ".word") {
2557 parseDirectiveWord(4, DirectiveID.getLoc());
2558 return false;
2559 }
2560
Jack Carter6ef6cc52013-11-19 20:53:28 +00002561 if (IDVal == ".mips_hack_elf_flags")
2562 return parseDirectiveMipsHackELFFlags();
2563
Jack Carter0cd3c192014-01-06 23:27:31 +00002564 if (IDVal == ".option")
2565 return parseDirectiveOption();
2566
2567 if (IDVal == ".abicalls") {
2568 getTargetStreamer().emitDirectiveAbiCalls();
2569 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2570 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2571 // Clear line
2572 Parser.eatToEndOfStatement();
2573 }
2574 return false;
2575 }
2576
Rafael Espindola870c4e92012-01-11 03:56:41 +00002577 return true;
2578}
2579
Rafael Espindola870c4e92012-01-11 03:56:41 +00002580extern "C" void LLVMInitializeMipsAsmParser() {
2581 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2582 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2583 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2584 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2585}
Jack Carterb4dbc172012-09-05 23:34:03 +00002586
2587#define GET_REGISTER_MATCHER
2588#define GET_MATCHER_IMPLEMENTATION
2589#include "MipsGenAsmMatcher.inc"