blob: 378235e1aaf6b3cf48d6980a1d9ad2eaf786db61 [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
Petar Jovanovica5da5882014-02-04 18:41:57 +000010#include "MCTargetDesc/MipsMCExpr.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000011#include "MCTargetDesc/MipsMCTargetDesc.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000012#include "MipsRegisterInfo.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000013#include "MipsTargetStreamer.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000014#include "llvm/ADT/APInt.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000015#include "llvm/ADT/StringSwitch.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000019#include "llvm/MC/MCParser/MCAsmLexer.h"
20#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000021#include "llvm/MC/MCStreamer.h"
22#include "llvm/MC/MCSubtargetInfo.h"
23#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000024#include "llvm/MC/MCTargetAsmParser.h"
Matheus Almeidae0d75aa2013-12-13 11:11:02 +000025#include "llvm/Support/MathExtras.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000026#include "llvm/Support/TargetRegistry.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000027
28using namespace llvm;
29
Joey Gouly0e76fa72013-09-12 10:28:05 +000030namespace llvm {
31class MCInstrInfo;
32}
33
Rafael Espindola870c4e92012-01-11 03:56:41 +000034namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000035class MipsAssemblerOptions {
36public:
Vladimir Medic4c299852013-11-06 11:27:05 +000037 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
Jack Carterb4dbc172012-09-05 23:34:03 +000038
Vladimir Medic4c299852013-11-06 11:27:05 +000039 unsigned getATRegNum() { return aTReg; }
Jack Carter0b744b32012-10-04 02:29:46 +000040 bool setATReg(unsigned Reg);
41
Vladimir Medic4c299852013-11-06 11:27:05 +000042 bool isReorder() { return reorder; }
43 void setReorder() { reorder = true; }
44 void setNoreorder() { reorder = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000045
Vladimir Medic4c299852013-11-06 11:27:05 +000046 bool isMacro() { return macro; }
47 void setMacro() { macro = true; }
48 void setNomacro() { macro = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000049
50private:
51 unsigned aTReg;
52 bool reorder;
53 bool macro;
54};
55}
56
57namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000058class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000059
Rafael Espindolaa17151a2013-10-08 13:08:17 +000060 MipsTargetStreamer &getTargetStreamer() {
Rafael Espindola4a1a3602014-01-14 01:21:46 +000061 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
Rafael Espindolaa17151a2013-10-08 13:08:17 +000062 return static_cast<MipsTargetStreamer &>(TS);
63 }
64
Jack Carterb4dbc172012-09-05 23:34:03 +000065 MCSubtargetInfo &STI;
66 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000067 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000068 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000069
Akira Hatanaka7605630c2012-08-17 20:16:42 +000070#define GET_ASSEMBLER_HEADER
71#include "MipsGenAsmMatcher.inc"
72
Chad Rosier49963552012-10-13 00:26:04 +000073 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Vladimir Medic4c299852013-11-06 11:27:05 +000074 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000075 MCStreamer &Out, unsigned &ErrorInfo,
76 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000077
78 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
79
Chad Rosierf0e87202012-10-25 20:41:34 +000080 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
81 SMLoc NameLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +000082 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000083
84 bool ParseDirective(AsmToken DirectiveID);
85
Jack Carterb4dbc172012-09-05 23:34:03 +000086 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000087 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000088
89 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000090 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Jack Carter5dc8ac92013-09-25 23:50:44 +000091
92 MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +000093 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
94 int RegKind);
95
96 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000097 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000098
Vladimir Medic4c299852013-11-06 11:27:05 +000099 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
100 int RegKind);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000101
102 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000103 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000104
Jack Carter873c7242013-01-12 01:03:14 +0000105 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000106 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000107
108 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000109 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000110
111 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000112 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000113
114 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000115 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000116
Vladimir Medic233dd512013-06-24 10:05:34 +0000117 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000118 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000119
120 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000121 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000122
123 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000124 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000125
Vladimir Medic643b3982013-07-30 10:12:14 +0000126 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000127 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000128
129 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000130 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic643b3982013-07-30 10:12:14 +0000131
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000132 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000133 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000134
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000135 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000136 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000137
138 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000139 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000140
Vladimir Medic05bcde62013-09-16 10:29:42 +0000141 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000142 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic05bcde62013-09-16 10:29:42 +0000143
Jack Carter5dc8ac92013-09-25 23:50:44 +0000144 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000145 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000146
147 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000148 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000149
150 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000151 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000152
153 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000154 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000155
Vladimir Medic2b953d02013-10-01 09:48:56 +0000156 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000157 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000158
159 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000160 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic2b953d02013-10-01 09:48:56 +0000161
Matheus Almeida779c5932013-11-18 12:32:49 +0000162 MipsAsmParser::OperandMatchResultTy
163 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
164
Jack Carter3b2c96e2014-01-22 23:31:38 +0000165 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000166 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000167
Vladimir Medic4c299852013-11-06 11:27:05 +0000168 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
Jack Carterb4dbc172012-09-05 23:34:03 +0000169 StringRef Mnemonic);
170
Jack Carter873c7242013-01-12 01:03:14 +0000171 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000172
Vladimir Medic4c299852013-11-06 11:27:05 +0000173 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000174 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000175
Jack Carter30a59822012-10-04 04:03:53 +0000176 bool needsExpansion(MCInst &Inst);
177
178 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000179 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000180 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000181 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000182 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
184 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000186 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000187 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
188 bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000189 bool reportParseError(StringRef ErrorMsg);
190
Jack Carterb5cf5902013-04-17 00:18:04 +0000191 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000192 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000193
Vladimir Medic4c299852013-11-06 11:27:05 +0000194 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000195
196 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000197 bool parseDirectiveSet();
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()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000267
268 // Assert exactly one ABI was chosen.
269 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
270 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
271 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
272 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000273 }
274
Jack Carterb4dbc172012-09-05 23:34:03 +0000275 MCAsmParser &getParser() const { return Parser; }
276 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000277};
278}
279
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000280namespace {
281
282/// MipsOperand - Instances of this class represent a parsed Mips machine
283/// instruction.
284class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000285
Jack Carter873c7242013-01-12 01:03:14 +0000286public:
287 enum RegisterKind {
288 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000289 Kind_GPR32,
290 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000291 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000292 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000293 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000294 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000295 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000296 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000297 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000298 Kind_ACC64DSP,
299 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000300 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000301 Kind_COP2,
302 Kind_MSA128BRegs,
303 Kind_MSA128HRegs,
304 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000305 Kind_MSA128DRegs,
306 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000307 };
308
309private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000310 enum KindTy {
311 k_CondCode,
312 k_CoprocNum,
313 k_Immediate,
314 k_Memory,
315 k_PostIndexRegister,
316 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000317 k_PtrReg,
Matheus Almeida779c5932013-11-18 12:32:49 +0000318 k_Token,
319 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000320 } Kind;
321
322 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000323
Eric Christopher8996c5d2013-03-15 00:42:55 +0000324 struct Token {
325 const char *Data;
326 unsigned Length;
327 };
328
329 struct RegOp {
330 unsigned RegNum;
331 RegisterKind Kind;
332 };
333
334 struct ImmOp {
335 const MCExpr *Val;
336 };
337
338 struct MemOp {
339 unsigned Base;
340 const MCExpr *Off;
341 };
342
Jack Carterb4dbc172012-09-05 23:34:03 +0000343 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000344 struct Token Tok;
345 struct RegOp Reg;
346 struct ImmOp Imm;
347 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000348 };
349
350 SMLoc StartLoc, EndLoc;
351
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000352public:
353 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000354 assert(N == 1 && "Invalid number of operands!");
355 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000356 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000357
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000358 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
359 assert(N == 1 && "Invalid number of operands!");
360 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
361 }
362
Vladimir Medic4c299852013-11-06 11:27:05 +0000363 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000364 // Add as immediate when possible. Null MCExpr = 0.
365 if (Expr == 0)
366 Inst.addOperand(MCOperand::CreateImm(0));
367 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
368 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
369 else
370 Inst.addOperand(MCOperand::CreateExpr(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 addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000374 assert(N == 1 && "Invalid number of operands!");
375 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000376 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000377 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000378
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000379 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000380 assert(N == 2 && "Invalid number of operands!");
381
382 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
383
384 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000385 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000386 }
387
388 bool isReg() const { return Kind == k_Register; }
389 bool isImm() const { return Kind == k_Immediate; }
390 bool isToken() const { return Kind == k_Token; }
391 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000392 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000393 bool isInvNum() const { return Kind == k_Immediate; }
Matheus Almeida779c5932013-11-18 12:32:49 +0000394 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000395
396 StringRef getToken() const {
397 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000398 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000399 }
400
401 unsigned getReg() const {
402 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000403 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000404 }
405
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000406 unsigned getPtrReg() const {
407 assert((Kind == k_PtrReg) && "Invalid access!");
408 return Reg.RegNum;
409 }
410
Jack Carter873c7242013-01-12 01:03:14 +0000411 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000412 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000413 Reg.Kind = RegKind;
414 }
415
Jack Carterb4dbc172012-09-05 23:34:03 +0000416 const MCExpr *getImm() const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000417 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000418 return Imm.Val;
419 }
420
Jack Carterdc1e35d2012-09-06 20:00:02 +0000421 unsigned getMemBase() const {
422 assert((Kind == k_Memory) && "Invalid access!");
423 return Mem.Base;
424 }
425
426 const MCExpr *getMemOff() const {
427 assert((Kind == k_Memory) && "Invalid access!");
428 return Mem.Off;
429 }
430
Jack Carterb4dbc172012-09-05 23:34:03 +0000431 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
432 MipsOperand *Op = new MipsOperand(k_Token);
433 Op->Tok.Data = Str.data();
434 Op->Tok.Length = Str.size();
435 Op->StartLoc = S;
436 Op->EndLoc = S;
437 return Op;
438 }
439
440 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
441 MipsOperand *Op = new MipsOperand(k_Register);
442 Op->Reg.RegNum = RegNum;
443 Op->StartLoc = S;
444 Op->EndLoc = E;
445 return Op;
446 }
447
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000448 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
449 MipsOperand *Op = new MipsOperand(k_PtrReg);
450 Op->Reg.RegNum = RegNum;
451 Op->StartLoc = S;
452 Op->EndLoc = E;
453 return Op;
454 }
455
Jack Carterb4dbc172012-09-05 23:34:03 +0000456 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
457 MipsOperand *Op = new MipsOperand(k_Immediate);
458 Op->Imm.Val = Val;
459 Op->StartLoc = S;
460 Op->EndLoc = E;
461 return Op;
462 }
463
Matheus Almeida779c5932013-11-18 12:32:49 +0000464 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
465 MipsOperand *Op = new MipsOperand(k_LSAImm);
466 Op->Imm.Val = Val;
467 Op->StartLoc = S;
468 Op->EndLoc = E;
469 return Op;
470 }
471
Jack Carter3b2c96e2014-01-22 23:31:38 +0000472 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
473 SMLoc E) {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000474 MipsOperand *Op = new MipsOperand(k_Memory);
475 Op->Mem.Base = Base;
476 Op->Mem.Off = Off;
477 Op->StartLoc = S;
478 Op->EndLoc = E;
479 return Op;
480 }
481
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000482 bool isGPR32Asm() const {
483 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000484 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000485 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000486 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
487 }
488
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000489 bool isGPR64Asm() const {
490 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000491 }
Jack Carter873c7242013-01-12 01:03:14 +0000492
493 bool isHWRegsAsm() const {
494 assert((Kind == k_Register) && "Invalid access!");
495 return Reg.Kind == Kind_HWRegs;
496 }
Jack Carter873c7242013-01-12 01:03:14 +0000497
Jack Carter873c7242013-01-12 01:03:14 +0000498 bool isCCRAsm() const {
499 assert((Kind == k_Register) && "Invalid access!");
500 return Reg.Kind == Kind_CCRRegs;
501 }
502
Vladimir Medic4c299852013-11-06 11:27:05 +0000503 bool isAFGR64Asm() const {
Vladimir Medic233dd512013-06-24 10:05:34 +0000504 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
505 }
506
507 bool isFGR64Asm() const {
508 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
509 }
510
511 bool isFGR32Asm() const {
512 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
513 }
514
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000515 bool isFGRH32Asm() const {
516 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
517 }
518
Vladimir Medic643b3982013-07-30 10:12:14 +0000519 bool isFCCRegsAsm() const {
520 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
521 }
522
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000523 bool isACC64DSPAsm() const {
524 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000525 }
526
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000527 bool isLO32DSPAsm() const {
528 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
529 }
530
531 bool isHI32DSPAsm() const {
532 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
533 }
534
Vladimir Medic4c299852013-11-06 11:27:05 +0000535 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
Vladimir Medic05bcde62013-09-16 10:29:42 +0000536
Jack Carter5dc8ac92013-09-25 23:50:44 +0000537 bool isMSA128BAsm() const {
538 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
539 }
540
541 bool isMSA128HAsm() const {
542 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
543 }
544
545 bool isMSA128WAsm() const {
546 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
547 }
548
549 bool isMSA128DAsm() const {
550 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
551 }
552
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000553 bool isMSA128CRAsm() const {
554 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
555 }
556
Jack Carterb4dbc172012-09-05 23:34:03 +0000557 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000558 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000559 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000560 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000561
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000562 virtual void print(raw_ostream &OS) const {
563 llvm_unreachable("unimplemented!");
564 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000565}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000566} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000567
Jack Carter9e65aa32013-03-22 00:05:30 +0000568namespace llvm {
569extern const MCInstrDesc MipsInsts[];
570}
571static const MCInstrDesc &getInstDesc(unsigned Opcode) {
572 return MipsInsts[Opcode];
573}
574
575bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000576 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000577 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
578 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000579
580 if (MCID.isBranch() || MCID.isCall()) {
581 const unsigned Opcode = Inst.getOpcode();
582 MCOperand Offset;
583
584 switch (Opcode) {
585 default:
586 break;
587 case Mips::BEQ:
588 case Mips::BNE:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000589 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000590 Offset = Inst.getOperand(2);
591 if (!Offset.isImm())
592 break; // We'll deal with this situation later on when applying fixups.
593 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
594 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000595 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000596 return Error(IDLoc, "branch to misaligned address");
597 break;
598 case Mips::BGEZ:
599 case Mips::BGTZ:
600 case Mips::BLEZ:
601 case Mips::BLTZ:
602 case Mips::BGEZAL:
603 case Mips::BLTZAL:
604 case Mips::BC1F:
605 case Mips::BC1T:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000606 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000607 Offset = Inst.getOperand(1);
608 if (!Offset.isImm())
609 break; // We'll deal with this situation later on when applying fixups.
610 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
611 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000612 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000613 return Error(IDLoc, "branch to misaligned address");
614 break;
615 }
616 }
617
Jack Carterc15c1d22013-04-25 23:31:35 +0000618 if (MCID.hasDelaySlot() && Options.isReorder()) {
619 // If this instruction has a delay slot and .set reorder is active,
620 // emit a NOP after it.
621 Instructions.push_back(Inst);
622 MCInst NopInst;
623 NopInst.setOpcode(Mips::SLL);
624 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
625 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
626 NopInst.addOperand(MCOperand::CreateImm(0));
627 Instructions.push_back(NopInst);
628 return false;
629 }
630
Jack Carter9e65aa32013-03-22 00:05:30 +0000631 if (MCID.mayLoad() || MCID.mayStore()) {
632 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000633 // reference or immediate we may have to expand instructions.
634 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000635 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000636 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
637 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000638 MCOperand &Op = Inst.getOperand(i);
639 if (Op.isImm()) {
640 int MemOffset = Op.getImm();
641 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000642 // Offset can't exceed 16bit value.
643 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000644 return false;
645 }
646 } else if (Op.isExpr()) {
647 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000648 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000649 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000650 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000651 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000652 // Expand symbol.
653 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000654 return false;
655 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000656 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000657 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000658 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000659 }
660 }
661 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000662 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000663 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000664
665 if (needsExpansion(Inst))
666 expandInstruction(Inst, IDLoc, Instructions);
667 else
668 Instructions.push_back(Inst);
669
670 return false;
671}
672
Jack Carter30a59822012-10-04 04:03:53 +0000673bool MipsAsmParser::needsExpansion(MCInst &Inst) {
674
Jack Carterd0bd6422013-04-18 00:41:53 +0000675 switch (Inst.getOpcode()) {
676 case Mips::LoadImm32Reg:
677 case Mips::LoadAddr32Imm:
678 case Mips::LoadAddr32Reg:
679 return true;
680 default:
681 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000682 }
683}
Jack Carter92995f12012-10-06 00:53:28 +0000684
Jack Carter30a59822012-10-04 04:03:53 +0000685void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000686 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000687 switch (Inst.getOpcode()) {
688 case Mips::LoadImm32Reg:
689 return expandLoadImm(Inst, IDLoc, Instructions);
690 case Mips::LoadAddr32Imm:
691 return expandLoadAddressImm(Inst, IDLoc, Instructions);
692 case Mips::LoadAddr32Reg:
693 return expandLoadAddressReg(Inst, IDLoc, Instructions);
694 }
Jack Carter30a59822012-10-04 04:03:53 +0000695}
Jack Carter92995f12012-10-06 00:53:28 +0000696
Jack Carter30a59822012-10-04 04:03:53 +0000697void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000698 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000699 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000700 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000701 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000702 const MCOperand &RegOp = Inst.getOperand(0);
703 assert(RegOp.isReg() && "expected register operand kind");
704
705 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000706 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000707 if (0 <= ImmValue && ImmValue <= 65535) {
708 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000709 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000710 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000711 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000712 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000713 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000714 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000715 } else if (ImmValue < 0 && ImmValue >= -32768) {
716 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000717 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000718 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000719 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000720 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000721 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000722 Instructions.push_back(tmpInst);
723 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000724 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000725 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000726 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000727 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000728 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
729 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000730 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000731 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000732 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000733 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
734 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
735 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
736 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000737 Instructions.push_back(tmpInst);
738 }
739}
Jack Carter92995f12012-10-06 00:53:28 +0000740
Vladimir Medic4c299852013-11-06 11:27:05 +0000741void
742MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
743 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000744 MCInst tmpInst;
745 const MCOperand &ImmOp = Inst.getOperand(2);
746 assert(ImmOp.isImm() && "expected immediate operand kind");
747 const MCOperand &SrcRegOp = Inst.getOperand(1);
748 assert(SrcRegOp.isReg() && "expected register operand kind");
749 const MCOperand &DstRegOp = Inst.getOperand(0);
750 assert(DstRegOp.isReg() && "expected register operand kind");
751 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000752 if (-32768 <= ImmValue && ImmValue <= 65535) {
753 // For -32768 <= j <= 65535.
754 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000755 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000756 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
757 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
758 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
759 Instructions.push_back(tmpInst);
760 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000761 // For any other value of j that is representable as a 32-bit integer.
762 // la d,j(s) => lui d,hi16(j)
763 // ori d,d,lo16(j)
764 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000765 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000766 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
767 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
768 Instructions.push_back(tmpInst);
769 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000770 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000771 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
772 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
773 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
774 Instructions.push_back(tmpInst);
775 tmpInst.clear();
776 tmpInst.setOpcode(Mips::ADDu);
777 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
778 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
779 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
780 Instructions.push_back(tmpInst);
781 }
782}
783
Vladimir Medic4c299852013-11-06 11:27:05 +0000784void
785MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
786 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000787 MCInst tmpInst;
788 const MCOperand &ImmOp = Inst.getOperand(1);
789 assert(ImmOp.isImm() && "expected immediate operand kind");
790 const MCOperand &RegOp = Inst.getOperand(0);
791 assert(RegOp.isReg() && "expected register operand kind");
792 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000793 if (-32768 <= ImmValue && ImmValue <= 65535) {
794 // For -32768 <= j <= 65535.
795 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000796 tmpInst.setOpcode(Mips::ADDiu);
797 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000798 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000799 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
800 Instructions.push_back(tmpInst);
801 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000802 // For any other value of j that is representable as a 32-bit integer.
803 // la d,j => lui d,hi16(j)
804 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000805 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000806 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
807 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
808 Instructions.push_back(tmpInst);
809 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000810 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000811 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
812 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
813 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
814 Instructions.push_back(tmpInst);
815 }
816}
817
Jack Carter9e65aa32013-03-22 00:05:30 +0000818void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000819 SmallVectorImpl<MCInst> &Instructions,
820 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000821 const MCSymbolRefExpr *SR;
822 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000823 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000824 const MCExpr *ExprOffset;
825 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000826 unsigned AtRegNum = getReg(
827 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000828 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000829 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
830 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000831 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000832 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
833 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000834 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000835 if (isImmOpnd) {
836 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
837 ImmOffset = Inst.getOperand(2).getImm();
838 LoOffset = ImmOffset & 0x0000ffff;
839 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000840 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000841 if (LoOffset & 0x8000)
842 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000843 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000844 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000845 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000846 TempInst.setLoc(IDLoc);
847 // 1st instruction in expansion is LUi. For load instruction we can use
848 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000849 // but for stores we must use $at.
850 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000851 TempInst.setOpcode(Mips::LUi);
852 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
853 if (isImmOpnd)
854 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
855 else {
856 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000857 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000858 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
859 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
860 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000861 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000862 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000863 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000864 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000865 }
866 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000867 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000868 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000869 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000870 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000871 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000872 TempInst.setOpcode(Mips::ADDu);
873 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
874 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
875 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
876 Instructions.push_back(TempInst);
877 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +0000878 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000879 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000880 TempInst.setOpcode(Inst.getOpcode());
881 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
882 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
883 if (isImmOpnd)
884 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
885 else {
886 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000887 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
888 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
889 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000890 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000891 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000892 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000893 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000894 }
895 }
896 Instructions.push_back(TempInst);
897 TempInst.clear();
898}
899
Vladimir Medic4c299852013-11-06 11:27:05 +0000900bool MipsAsmParser::MatchAndEmitInstruction(
901 SMLoc IDLoc, unsigned &Opcode,
902 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
903 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000904 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000905 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000906 unsigned MatchResult =
907 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000908
909 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000910 default:
911 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000912 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000913 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000914 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000915 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +0000916 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +0000917 return false;
918 }
919 case Match_MissingFeature:
920 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
921 return true;
922 case Match_InvalidOperand: {
923 SMLoc ErrorLoc = IDLoc;
924 if (ErrorInfo != ~0U) {
925 if (ErrorInfo >= Operands.size())
926 return Error(IDLoc, "too few operands for instruction");
927
Vladimir Medic4c299852013-11-06 11:27:05 +0000928 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000929 if (ErrorLoc == SMLoc())
930 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000931 }
932
933 return Error(ErrorLoc, "invalid operand for instruction");
934 }
935 case Match_MnemonicFail:
936 return Error(IDLoc, "invalid instruction");
937 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000938 return true;
939}
940
Jack Carter1ac53222013-02-20 23:11:17 +0000941int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000942 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +0000943
944 if (Name == "at")
945 return getATReg();
946
Vladimir Medic4c299852013-11-06 11:27:05 +0000947 CC = StringSwitch<unsigned>(Name)
948 .Case("zero", 0)
949 .Case("a0", 4)
950 .Case("a1", 5)
951 .Case("a2", 6)
952 .Case("a3", 7)
953 .Case("v0", 2)
954 .Case("v1", 3)
955 .Case("s0", 16)
956 .Case("s1", 17)
957 .Case("s2", 18)
958 .Case("s3", 19)
959 .Case("s4", 20)
960 .Case("s5", 21)
961 .Case("s6", 22)
962 .Case("s7", 23)
963 .Case("k0", 26)
964 .Case("k1", 27)
965 .Case("sp", 29)
966 .Case("fp", 30)
967 .Case("gp", 28)
968 .Case("ra", 31)
969 .Case("t0", 8)
970 .Case("t1", 9)
971 .Case("t2", 10)
972 .Case("t3", 11)
973 .Case("t4", 12)
974 .Case("t5", 13)
975 .Case("t6", 14)
976 .Case("t7", 15)
977 .Case("t8", 24)
978 .Case("t9", 25)
979 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000980
Jack Carterd0bd6422013-04-18 00:41:53 +0000981 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000982 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
983 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000984 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000985 CC += 4;
986
987 if (CC == -1 && isMips64())
988 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +0000989 .Case("a4", 8)
990 .Case("a5", 9)
991 .Case("a6", 10)
992 .Case("a7", 11)
993 .Case("kt0", 26)
994 .Case("kt1", 27)
995 .Case("s8", 30)
996 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000997
998 return CC;
999}
Jack Carterd0bd6422013-04-18 00:41:53 +00001000
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001001int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001002
Jack Cartera63b16a2012-09-07 00:23:42 +00001003 if (Name[0] == 'f') {
1004 StringRef NumString = Name.substr(1);
1005 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001006 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001007 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001008 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001009 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001010 return IntVal;
1011 }
1012 return -1;
1013}
Jack Cartera63b16a2012-09-07 00:23:42 +00001014
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001015int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1016
1017 if (Name.startswith("fcc")) {
1018 StringRef NumString = Name.substr(3);
1019 unsigned IntVal;
1020 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001021 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001022 if (IntVal > 7) // There are only 8 fcc registers.
1023 return -1;
1024 return IntVal;
1025 }
1026 return -1;
1027}
1028
1029int MipsAsmParser::matchACRegisterName(StringRef Name) {
1030
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001031 if (Name.startswith("ac")) {
1032 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001033 unsigned IntVal;
1034 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001035 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001036 if (IntVal > 3) // There are only 3 acc registers.
1037 return -1;
1038 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001039 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001040 return -1;
1041}
Jack Carterd0bd6422013-04-18 00:41:53 +00001042
Jack Carter5dc8ac92013-09-25 23:50:44 +00001043int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1044 unsigned IntVal;
1045
1046 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1047 return -1;
1048
1049 if (IntVal > 31)
1050 return -1;
1051
1052 return IntVal;
1053}
1054
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001055int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1056 int CC;
1057
1058 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001059 .Case("msair", 0)
1060 .Case("msacsr", 1)
1061 .Case("msaaccess", 2)
1062 .Case("msasave", 3)
1063 .Case("msamodify", 4)
1064 .Case("msarequest", 5)
1065 .Case("msamap", 6)
1066 .Case("msaunmap", 7)
1067 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001068
1069 return CC;
1070}
1071
Vladimir Medic8cd17102013-06-20 11:21:49 +00001072int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1073
Vladimir Medic8cd17102013-06-20 11:21:49 +00001074 int CC;
1075 CC = matchCPURegisterName(Name);
1076 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001077 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1078 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001079 CC = matchFPURegisterName(Name);
Vladimir Medic4c299852013-11-06 11:27:05 +00001080 // TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001081 if (CC != -1)
1082 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1083 : Mips::FGR32RegClassID);
1084 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001085}
1086
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001087int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001088
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001089 switch (RegKind) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001090 case MipsOperand::Kind_GPR32:
1091 return Mips::GPR32RegClassID;
1092 case MipsOperand::Kind_GPR64:
1093 return Mips::GPR64RegClassID;
1094 case MipsOperand::Kind_HWRegs:
1095 return Mips::HWRegsRegClassID;
1096 case MipsOperand::Kind_FGR32Regs:
1097 return Mips::FGR32RegClassID;
1098 case MipsOperand::Kind_FGRH32Regs:
1099 return Mips::FGRH32RegClassID;
1100 case MipsOperand::Kind_FGR64Regs:
1101 return Mips::FGR64RegClassID;
1102 case MipsOperand::Kind_AFGR64Regs:
1103 return Mips::AFGR64RegClassID;
1104 case MipsOperand::Kind_CCRRegs:
1105 return Mips::CCRRegClassID;
1106 case MipsOperand::Kind_ACC64DSP:
1107 return Mips::ACC64DSPRegClassID;
1108 case MipsOperand::Kind_FCCRegs:
1109 return Mips::FCCRegClassID;
1110 case MipsOperand::Kind_MSA128BRegs:
1111 return Mips::MSA128BRegClassID;
1112 case MipsOperand::Kind_MSA128HRegs:
1113 return Mips::MSA128HRegClassID;
1114 case MipsOperand::Kind_MSA128WRegs:
1115 return Mips::MSA128WRegClassID;
1116 case MipsOperand::Kind_MSA128DRegs:
1117 return Mips::MSA128DRegClassID;
1118 case MipsOperand::Kind_MSA128CtrlRegs:
1119 return Mips::MSACtrlRegClassID;
1120 default:
1121 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001122 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001123}
Jack Carterb4dbc172012-09-05 23:34:03 +00001124
Jack Carter0b744b32012-10-04 02:29:46 +00001125bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1126 if (Reg > 31)
1127 return false;
1128
1129 aTReg = Reg;
1130 return true;
1131}
1132
Vladimir Medic4c299852013-11-06 11:27:05 +00001133int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
Jack Carter0b744b32012-10-04 02:29:46 +00001134
Jack Carterd0bd6422013-04-18 00:41:53 +00001135unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001136 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001137}
1138
Jack Carter873c7242013-01-12 01:03:14 +00001139int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001140 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001141 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001142 return -1;
1143
Jack Carter873c7242013-01-12 01:03:14 +00001144 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001145}
1146
Jack Carter873c7242013-01-12 01:03:14 +00001147int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001148 const AsmToken &Tok = Parser.getTok();
1149 int RegNum = -1;
1150
1151 if (Tok.is(AsmToken::Identifier)) {
1152 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001153 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001154 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001155 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001156 is64BitReg ? Mips::GPR64RegClassID
1157 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001158 return RegNum;
1159}
1160
Jack Carterd0bd6422013-04-18 00:41:53 +00001161bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001162 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001163
1164 SMLoc S = Parser.getTok().getLoc();
1165 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001166
Jack Carter873c7242013-01-12 01:03:14 +00001167 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001168 if (RegNo == -1)
1169 return true;
1170
Vladimir Medic4c299852013-11-06 11:27:05 +00001171 Operands.push_back(
1172 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001173 Parser.Lex(); // Eat register token.
1174 return false;
1175}
1176
Vladimir Medic4c299852013-11-06 11:27:05 +00001177bool
1178MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1179 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001180 // Check if the current operand has a custom associated parser, if so, try to
1181 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001182 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1183 if (ResTy == MatchOperand_Success)
1184 return false;
1185 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1186 // there was a match, but an error occurred, in which case, just return that
1187 // the operand parsing failed.
1188 if (ResTy == MatchOperand_ParseFail)
1189 return true;
1190
1191 switch (getLexer().getKind()) {
1192 default:
1193 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1194 return true;
1195 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001196 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001197 SMLoc S = Parser.getTok().getLoc();
1198 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001199 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001200 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001201 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001202 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001203 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001204 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001205 if (getLexer().isNot(AsmToken::Dollar))
1206 return true;
1207
Jack Carterd0bd6422013-04-18 00:41:53 +00001208 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001209 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001210 return true;
1211
1212 if (!getLexer().is(AsmToken::RParen))
1213 return true;
1214
1215 S = Parser.getTok().getLoc();
1216 Operands.push_back(MipsOperand::CreateToken(")", S));
1217 Parser.Lex();
1218 }
1219 return false;
1220 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001221 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001222 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001223 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001224 return true;
1225
Jack Carter873c7242013-01-12 01:03:14 +00001226 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001227 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001228 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001229 const MCExpr *Res =
1230 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001231
1232 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1233 return false;
1234 }
1235 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001236 // For instruction aliases like "bc1f $Label" dedicated parser will
1237 // eat the '$' sign before failing. So in order to look for appropriate
1238 // label we must check first if we have already consumed '$'.
1239 if (hasConsumedDollar) {
1240 hasConsumedDollar = false;
1241 SMLoc S = Parser.getTok().getLoc();
1242 StringRef Identifier;
1243 if (Parser.parseIdentifier(Identifier))
1244 return true;
1245 SMLoc E =
1246 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1247 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1248 // Create a symbol reference.
1249 const MCExpr *Res =
1250 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1251
1252 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1253 return false;
1254 }
Jack Carterd76b2372013-03-21 21:44:16 +00001255 // Look for the existing symbol, we should check if
Matheus Almeidad534fc32014-01-30 13:40:26 +00001256 // we need to assign the proper RegisterKind.
Jack Carterd0bd6422013-04-18 00:41:53 +00001257 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1258 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001259 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001260 case AsmToken::LParen:
1261 case AsmToken::Minus:
1262 case AsmToken::Plus:
1263 case AsmToken::Integer:
1264 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001265 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001266 const MCExpr *IdVal;
1267 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001268 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001269 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001270 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001271 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1272 return false;
1273 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001274 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001275 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001276 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001277 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001278 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001279 return true;
1280
Jack Carter873c7242013-01-12 01:03:14 +00001281 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1282
Jack Carterdc1e35d2012-09-06 20:00:02 +00001283 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1284 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001285 } // case AsmToken::Percent
1286 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001287 return true;
1288}
1289
Vladimir Medic4c299852013-11-06 11:27:05 +00001290const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001291 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001292 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001293 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001294 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001295 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001296 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001297 short Val = MCE->getValue();
1298 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001299 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001300 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001301 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001302 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001303 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001304 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001305 if (LoSign)
1306 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001307 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001308 } else {
1309 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001310 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001311 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001312 }
1313
Jack Carterb5cf5902013-04-17 00:18:04 +00001314 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001315 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001316 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001317 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001318 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001319 return Res;
1320 }
1321
1322 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001323 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1324
1325 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1326 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1327 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1328 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1329 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1330 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1331 return MipsMCExpr::CreateHi(Expr, getContext());
1332 return MipsMCExpr::CreateLo(Expr, getContext());
1333 }
1334
Jack Carterd0bd6422013-04-18 00:41:53 +00001335 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1336 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001337 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1338 return Res;
1339 }
1340
1341 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001342 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1343 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1344 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001345 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001346 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001347 return Expr;
1348}
1349
1350bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1351
1352 switch (Expr->getKind()) {
1353 case MCExpr::Constant:
1354 return true;
1355 case MCExpr::SymbolRef:
1356 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1357 case MCExpr::Binary:
1358 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1359 if (!isEvaluated(BE->getLHS()))
1360 return false;
1361 return isEvaluated(BE->getRHS());
1362 }
1363 case MCExpr::Unary:
1364 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001365 case MCExpr::Target:
1366 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001367 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001368 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001369}
Jack Carterd0bd6422013-04-18 00:41:53 +00001370
Jack Carterb5cf5902013-04-17 00:18:04 +00001371bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001372 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001373 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001374 if (Tok.isNot(AsmToken::Identifier))
1375 return true;
1376
1377 std::string Str = Tok.getIdentifier().str();
1378
Jack Carterd0bd6422013-04-18 00:41:53 +00001379 Parser.Lex(); // Eat the identifier.
1380 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001381 const MCExpr *IdVal;
1382 SMLoc EndLoc;
1383
1384 if (getLexer().getKind() == AsmToken::LParen) {
1385 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001386 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001387 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001388 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001389 const AsmToken &nextTok = Parser.getTok();
1390 if (nextTok.isNot(AsmToken::Identifier))
1391 return true;
1392 Str += "(%";
1393 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001394 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001395 if (getLexer().getKind() != AsmToken::LParen)
1396 return true;
1397 } else
1398 break;
1399 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001400 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001401 return true;
1402
1403 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001404 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001405
1406 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001407 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001408
Jack Carterd0bd6422013-04-18 00:41:53 +00001409 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001410 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001411}
1412
Jack Carterb4dbc172012-09-05 23:34:03 +00001413bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1414 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001415 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001416 RegNo = tryParseRegister(isMips64());
1417 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001418 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001419}
1420
Jack Carterb5cf5902013-04-17 00:18:04 +00001421bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001422 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001423 bool Result = true;
1424
1425 while (getLexer().getKind() == AsmToken::LParen)
1426 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001427
Jack Carterd0bd6422013-04-18 00:41:53 +00001428 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001429 default:
1430 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001431 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001432 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001433 case AsmToken::Integer:
1434 case AsmToken::Minus:
1435 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001436 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001437 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001438 else
1439 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001440 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001441 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001442 break;
Jack Carter873c7242013-01-12 01:03:14 +00001443 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001444 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001445 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001446 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001447}
1448
Jack Carterb4dbc172012-09-05 23:34:03 +00001449MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001450 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001451
1452 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001453 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001454 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001455 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001456 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001457 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001458
Jack Carterb5cf5902013-04-17 00:18:04 +00001459 if (getLexer().getKind() == AsmToken::LParen) {
1460 Parser.Lex();
1461 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001462 }
1463
Jack Carterb5cf5902013-04-17 00:18:04 +00001464 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001465 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001466 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001467
Jack Carterd0bd6422013-04-18 00:41:53 +00001468 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001469 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001470 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001471 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001472 SMLoc E =
1473 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001474 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1475 return MatchOperand_Success;
1476 }
1477 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001478 SMLoc E =
1479 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001480
Jack Carterd0bd6422013-04-18 00:41:53 +00001481 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001482 Operands.push_back(MipsOperand::CreateMem(
1483 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001484 return MatchOperand_Success;
1485 }
1486 Error(Parser.getTok().getLoc(), "'(' expected");
1487 return MatchOperand_ParseFail;
1488 }
1489
Jack Carterd0bd6422013-04-18 00:41:53 +00001490 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001491 }
1492
Vladimir Medic4c299852013-11-06 11:27:05 +00001493 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1494 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001495 if (Res != MatchOperand_Success)
1496 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001497
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001498 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001499 Error(Parser.getTok().getLoc(), "')' expected");
1500 return MatchOperand_ParseFail;
1501 }
1502
Jack Carter873c7242013-01-12 01:03:14 +00001503 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1504
Jack Carterd0bd6422013-04-18 00:41:53 +00001505 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001506
1507 if (IdVal == 0)
1508 IdVal = MCConstantExpr::Create(0, getContext());
1509
Jack Carterd0bd6422013-04-18 00:41:53 +00001510 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001511 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001512 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001513 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001514 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001515 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001516 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1517 int64_t Imm;
1518 if (IdVal->EvaluateAsAbsolute(Imm))
1519 IdVal = MCConstantExpr::Create(Imm, getContext());
1520 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1521 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1522 getContext());
1523 }
1524
Jack Carterdc1e35d2012-09-06 20:00:02 +00001525 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1526 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001527 return MatchOperand_Success;
1528}
1529
Vladimir Medic4c299852013-11-06 11:27:05 +00001530bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1531 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001532 // If the first token is not '$' we have an error.
1533 if (Parser.getTok().isNot(AsmToken::Dollar))
1534 return false;
1535
1536 SMLoc S = Parser.getTok().getLoc();
1537 Parser.Lex();
1538 AsmToken::TokenKind TkKind = getLexer().getKind();
1539 int Reg;
1540
1541 if (TkKind == AsmToken::Integer) {
1542 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1543 regKindToRegClass(RegKind));
1544 if (Reg == -1)
1545 return false;
1546 } else if (TkKind == AsmToken::Identifier) {
1547 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1548 return false;
1549 Reg = getReg(regKindToRegClass(RegKind), Reg);
1550 } else {
1551 return false;
1552 }
1553
1554 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1555 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1556 Operands.push_back(Op);
1557 Parser.Lex();
1558 return true;
1559}
1560
1561MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001562MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1563 MipsOperand::RegisterKind RegKind =
1564 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001565
1566 // Parse index register.
1567 if (!parsePtrReg(Operands, RegKind))
1568 return MatchOperand_NoMatch;
1569
1570 // Parse '('.
1571 if (Parser.getTok().isNot(AsmToken::LParen))
1572 return MatchOperand_NoMatch;
1573
1574 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1575 Parser.Lex();
1576
1577 // Parse base register.
1578 if (!parsePtrReg(Operands, RegKind))
1579 return MatchOperand_NoMatch;
1580
1581 // Parse ')'.
1582 if (Parser.getTok().isNot(AsmToken::RParen))
1583 return MatchOperand_NoMatch;
1584
1585 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1586 Parser.Lex();
1587
1588 return MatchOperand_Success;
1589}
1590
Jack Carter873c7242013-01-12 01:03:14 +00001591MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001592MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001593 int RegKind) {
1594 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001595 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001596 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001597 return MatchOperand_Success;
1598 return MatchOperand_NoMatch;
1599 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001600 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001601 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001602 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001603 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001604 if (!hasConsumedDollar) {
1605 Parser.Lex(); // Eat the '$'
1606 hasConsumedDollar = true;
1607 }
1608 if (getLexer().getKind() == AsmToken::Identifier) {
1609 int RegNum = -1;
1610 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001611 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001612 switch (RegKind) {
1613 case MipsOperand::Kind_GPR32:
1614 case MipsOperand::Kind_GPR64:
1615 RegNum = matchCPURegisterName(RegName);
1616 break;
1617 case MipsOperand::Kind_AFGR64Regs:
1618 case MipsOperand::Kind_FGR64Regs:
1619 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001620 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001621 RegNum = matchFPURegisterName(RegName);
1622 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1623 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001624 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1625 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001626 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001627 break;
1628 case MipsOperand::Kind_FCCRegs:
1629 RegNum = matchFCCRegisterName(RegName);
1630 break;
1631 case MipsOperand::Kind_ACC64DSP:
1632 RegNum = matchACRegisterName(RegName);
1633 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001634 default:
1635 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001636 }
1637 // No match found, return _NoMatch to give a chance to other round.
1638 if (RegNum < 0)
1639 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001640
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001641 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1642 if (RegVal == -1)
1643 return MatchOperand_NoMatch;
1644
Vladimir Medic4c299852013-11-06 11:27:05 +00001645 MipsOperand *Op =
1646 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001647 Op->setRegKind(Kind);
1648 Operands.push_back(Op);
1649 hasConsumedDollar = false;
1650 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001651 return MatchOperand_Success;
1652 } else if (getLexer().getKind() == AsmToken::Integer) {
1653 unsigned RegNum = Parser.getTok().getIntVal();
1654 if (Kind == MipsOperand::Kind_HWRegs) {
1655 if (RegNum != 29)
1656 return MatchOperand_NoMatch;
1657 // Only hwreg 29 is supported, found at index 0.
1658 RegNum = 0;
1659 }
1660 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1661 if (Reg == -1)
1662 return MatchOperand_NoMatch;
1663 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1664 Op->setRegKind(Kind);
1665 Operands.push_back(Op);
1666 hasConsumedDollar = false;
1667 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001668 if ((RegKind == MipsOperand::Kind_GPR32) &&
1669 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001670 // Check if it is indexed addressing operand.
1671 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1672 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001673 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001674 return MatchOperand_NoMatch;
1675 if (getLexer().isNot(AsmToken::RParen))
1676 return MatchOperand_NoMatch;
1677 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1678 Parser.Lex();
1679 }
Jack Carter873c7242013-01-12 01:03:14 +00001680 return MatchOperand_Success;
1681 }
1682 return MatchOperand_NoMatch;
1683}
Vladimir Medic64828a12013-07-16 10:07:14 +00001684
Matheus Almeidab74293d2013-10-14 11:49:30 +00001685bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1686 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1687
1688 if (Val < 0)
1689 return false;
1690
1691 switch (Kind) {
1692 default:
1693 return false;
1694 case MipsOperand::Kind_MSA128BRegs:
1695 return Val < 16;
1696 case MipsOperand::Kind_MSA128HRegs:
1697 return Val < 8;
1698 case MipsOperand::Kind_MSA128WRegs:
1699 return Val < 4;
1700 case MipsOperand::Kind_MSA128DRegs:
1701 return Val < 2;
1702 }
1703}
1704
Vladimir Medic8cd17102013-06-20 11:21:49 +00001705MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001706MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001707 int RegKind) {
1708 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1709 SMLoc S = Parser.getTok().getLoc();
1710 std::string RegName;
1711
1712 if (Parser.getTok().isNot(AsmToken::Dollar))
1713 return MatchOperand_NoMatch;
1714
1715 switch (RegKind) {
1716 default:
1717 return MatchOperand_ParseFail;
1718 case MipsOperand::Kind_MSA128BRegs:
1719 case MipsOperand::Kind_MSA128HRegs:
1720 case MipsOperand::Kind_MSA128WRegs:
1721 case MipsOperand::Kind_MSA128DRegs:
1722 break;
1723 }
1724
1725 Parser.Lex(); // Eat the '$'.
1726 if (getLexer().getKind() == AsmToken::Identifier)
1727 RegName = Parser.getTok().getString().lower();
1728 else
1729 return MatchOperand_ParseFail;
1730
1731 int RegNum = matchMSA128RegisterName(RegName);
1732
1733 if (RegNum < 0 || RegNum > 31)
1734 return MatchOperand_ParseFail;
1735
1736 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1737 if (RegVal == -1)
1738 return MatchOperand_ParseFail;
1739
Vladimir Medic4c299852013-11-06 11:27:05 +00001740 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001741 Op->setRegKind(Kind);
1742 Operands.push_back(Op);
1743
1744 Parser.Lex(); // Eat the register identifier.
1745
Matheus Almeidab74293d2013-10-14 11:49:30 +00001746 // MSA registers may be suffixed with an index in the form of:
1747 // 1) Immediate expression.
1748 // 2) General Purpose Register.
1749 // Examples:
1750 // 1) copy_s.b $29,$w0[0]
1751 // 2) sld.b $w0,$w1[$1]
1752
1753 if (Parser.getTok().isNot(AsmToken::LBrac))
1754 return MatchOperand_Success;
1755
1756 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1757
1758 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1759 Parser.Lex(); // Parse the '[' token.
1760
1761 if (Parser.getTok().is(AsmToken::Dollar)) {
1762 // This must be a GPR.
1763 MipsOperand *RegOp;
1764 SMLoc VIdx = Parser.getTok().getLoc();
1765 Parser.Lex(); // Parse the '$' token.
1766
1767 // GPR have aliases and we must account for that. Example: $30 == $fp
1768 if (getLexer().getKind() == AsmToken::Integer) {
1769 unsigned RegNum = Parser.getTok().getIntVal();
1770 int Reg = matchRegisterByNumber(
1771 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1772 if (Reg == -1) {
1773 Error(VIdx, "invalid general purpose register");
1774 return MatchOperand_ParseFail;
1775 }
1776
1777 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1778 } else if (getLexer().getKind() == AsmToken::Identifier) {
1779 int RegNum = -1;
1780 std::string RegName = Parser.getTok().getString().lower();
1781
1782 RegNum = matchCPURegisterName(RegName);
1783 if (RegNum == -1) {
1784 Error(VIdx, "general purpose register expected");
1785 return MatchOperand_ParseFail;
1786 }
1787 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1788 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1789 } else
1790 return MatchOperand_ParseFail;
1791
1792 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1793 Operands.push_back(RegOp);
1794 Parser.Lex(); // Eat the register identifier.
1795
1796 if (Parser.getTok().isNot(AsmToken::RBrac))
1797 return MatchOperand_ParseFail;
1798
1799 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1800 Parser.Lex(); // Parse the ']' token.
1801
1802 return MatchOperand_Success;
1803 }
1804
1805 // The index must be a constant expression then.
1806 SMLoc VIdx = Parser.getTok().getLoc();
1807 const MCExpr *ImmVal;
1808
1809 if (getParser().parseExpression(ImmVal))
1810 return MatchOperand_ParseFail;
1811
1812 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1813 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1814 Error(VIdx, "invalid immediate value");
1815 return MatchOperand_ParseFail;
1816 }
1817
1818 SMLoc E = Parser.getTok().getEndLoc();
1819
1820 if (Parser.getTok().isNot(AsmToken::RBrac))
1821 return MatchOperand_ParseFail;
1822
Vladimir Medic4c299852013-11-06 11:27:05 +00001823 bool insve =
1824 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1825 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001826
1827 // The second vector index of insve instructions is always 0.
1828 if (insve && Operands.size() > 6) {
1829 if (expr->getValue() != 0) {
1830 Error(VIdx, "immediate value must be 0");
1831 return MatchOperand_ParseFail;
1832 }
1833 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1834 } else
1835 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1836
1837 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1838
1839 Parser.Lex(); // Parse the ']' token.
1840
Jack Carter5dc8ac92013-09-25 23:50:44 +00001841 return MatchOperand_Success;
1842}
1843
1844MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001845MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1846 int RegKind) {
1847 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1848
1849 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1850 return MatchOperand_NoMatch;
1851
1852 if (Parser.getTok().isNot(AsmToken::Dollar))
1853 return MatchOperand_ParseFail;
1854
1855 SMLoc S = Parser.getTok().getLoc();
1856
1857 Parser.Lex(); // Eat the '$' symbol.
1858
1859 int RegNum = -1;
1860 if (getLexer().getKind() == AsmToken::Identifier)
1861 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1862 else if (getLexer().getKind() == AsmToken::Integer)
1863 RegNum = Parser.getTok().getIntVal();
1864 else
1865 return MatchOperand_ParseFail;
1866
1867 if (RegNum < 0 || RegNum > 7)
1868 return MatchOperand_ParseFail;
1869
1870 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1871 if (RegVal == -1)
1872 return MatchOperand_ParseFail;
1873
Vladimir Medic4c299852013-11-06 11:27:05 +00001874 MipsOperand *RegOp =
1875 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001876 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1877 Operands.push_back(RegOp);
1878 Parser.Lex(); // Eat the register identifier.
1879
1880 return MatchOperand_Success;
1881}
1882
1883MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001884MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001885
1886 if (!isMips64())
1887 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001888 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001889}
1890
1891MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001892MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1893 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001894}
Jack Carter873c7242013-01-12 01:03:14 +00001895
Vladimir Medic4c299852013-11-06 11:27:05 +00001896MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1897 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001898
1899 if (isFP64())
1900 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001901 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001902}
1903
1904MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001905MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001906 if (!isFP64())
1907 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001908 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001909}
1910
1911MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001912MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1913 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1914}
1915
1916MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1917 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1918 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001919}
1920
Vladimir Medic643b3982013-07-30 10:12:14 +00001921MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001922MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1923 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001924}
1925
1926MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001927MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1928 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001929}
1930
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001931MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001932MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001933 // If the first token is not '$' we have an error.
1934 if (Parser.getTok().isNot(AsmToken::Dollar))
1935 return MatchOperand_NoMatch;
1936
1937 SMLoc S = Parser.getTok().getLoc();
1938 Parser.Lex(); // Eat the '$'
1939
1940 const AsmToken &Tok = Parser.getTok(); // Get next token.
1941
1942 if (Tok.isNot(AsmToken::Identifier))
1943 return MatchOperand_NoMatch;
1944
1945 if (!Tok.getIdentifier().startswith("ac"))
1946 return MatchOperand_NoMatch;
1947
1948 StringRef NumString = Tok.getIdentifier().substr(2);
1949
1950 unsigned IntVal;
1951 if (NumString.getAsInteger(10, IntVal))
1952 return MatchOperand_NoMatch;
1953
1954 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1955
1956 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1957 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1958 Operands.push_back(Op);
1959
1960 Parser.Lex(); // Eat the register number.
1961 return MatchOperand_Success;
1962}
1963
1964MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001965MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001966 // If the first token is not '$' we have an error.
1967 if (Parser.getTok().isNot(AsmToken::Dollar))
1968 return MatchOperand_NoMatch;
1969
1970 SMLoc S = Parser.getTok().getLoc();
1971 Parser.Lex(); // Eat the '$'
1972
1973 const AsmToken &Tok = Parser.getTok(); // Get next token.
1974
1975 if (Tok.isNot(AsmToken::Identifier))
1976 return MatchOperand_NoMatch;
1977
1978 if (!Tok.getIdentifier().startswith("ac"))
1979 return MatchOperand_NoMatch;
1980
1981 StringRef NumString = Tok.getIdentifier().substr(2);
1982
1983 unsigned IntVal;
1984 if (NumString.getAsInteger(10, IntVal))
1985 return MatchOperand_NoMatch;
1986
1987 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1988
1989 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1990 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1991 Operands.push_back(Op);
1992
1993 Parser.Lex(); // Eat the register number.
1994 return MatchOperand_Success;
1995}
1996
Vladimir Medic05bcde62013-09-16 10:29:42 +00001997MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001998MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00001999 // If the first token is not '$' we have an error.
2000 if (Parser.getTok().isNot(AsmToken::Dollar))
2001 return MatchOperand_NoMatch;
2002
2003 SMLoc S = Parser.getTok().getLoc();
2004 Parser.Lex(); // Eat the '$'
2005
2006 const AsmToken &Tok = Parser.getTok(); // Get next token.
2007
2008 if (Tok.isNot(AsmToken::Integer))
2009 return MatchOperand_NoMatch;
2010
2011 unsigned IntVal = Tok.getIntVal();
2012
2013 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2014
2015 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2016 Op->setRegKind(MipsOperand::Kind_COP2);
2017 Operands.push_back(Op);
2018
2019 Parser.Lex(); // Eat the register number.
2020 return MatchOperand_Success;
2021}
2022
Vladimir Medic4c299852013-11-06 11:27:05 +00002023MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2024 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2025 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002026}
2027
Vladimir Medic4c299852013-11-06 11:27:05 +00002028MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2029 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2030 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002031}
2032
Vladimir Medic4c299852013-11-06 11:27:05 +00002033MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2034 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2035 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002036}
2037
Vladimir Medic4c299852013-11-06 11:27:05 +00002038MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2039 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2040 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002041}
2042
Vladimir Medic4c299852013-11-06 11:27:05 +00002043MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2044 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2045 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002046}
2047
Jack Carterd0bd6422013-04-18 00:41:53 +00002048bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002049 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002050
2051 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2052 if (Sym) {
2053 SMLoc S = Parser.getTok().getLoc();
2054 const MCExpr *Expr;
2055 if (Sym->isVariable())
2056 Expr = Sym->getVariableValue();
2057 else
2058 return false;
2059 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002060 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2061 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002062 const StringRef DefSymbol = Ref->getSymbol().getName();
2063 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002064 int RegNum = -1;
2065 APInt IntVal(32, -1);
2066 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2067 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002068 isMips64() ? Mips::GPR64RegClassID
2069 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002070 else {
2071 // Lookup for the register with the corresponding name.
2072 switch (Kind) {
2073 case MipsOperand::Kind_AFGR64Regs:
2074 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002075 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002076 break;
2077 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002078 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002079 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002080 case MipsOperand::Kind_GPR64:
2081 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002082 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002083 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002084 break;
2085 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002086 if (RegNum > -1)
2087 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002088 }
Jack Carterd76b2372013-03-21 21:44:16 +00002089 if (RegNum > -1) {
2090 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002091 MipsOperand *op =
2092 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002093 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002094 Operands.push_back(op);
2095 return true;
2096 }
2097 }
2098 } else if (Expr->getKind() == MCExpr::Constant) {
2099 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002100 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2101 MipsOperand *op =
2102 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002103 Operands.push_back(op);
2104 return true;
2105 }
2106 }
2107 return false;
2108}
Jack Carterd0bd6422013-04-18 00:41:53 +00002109
Jack Carter873c7242013-01-12 01:03:14 +00002110MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002111MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2112 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002113}
2114
2115MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002116MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2117 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002118}
2119
Vladimir Medic2b953d02013-10-01 09:48:56 +00002120MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002121MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002122 const MCExpr *IdVal;
2123 // If the first token is '$' we may have register operand.
2124 if (Parser.getTok().is(AsmToken::Dollar))
2125 return MatchOperand_NoMatch;
2126 SMLoc S = Parser.getTok().getLoc();
2127 if (getParser().parseExpression(IdVal))
2128 return MatchOperand_ParseFail;
2129 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002130 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002131 int64_t Val = MCE->getValue();
2132 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2133 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002134 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002135 return MatchOperand_Success;
2136}
2137
Matheus Almeida779c5932013-11-18 12:32:49 +00002138MipsAsmParser::OperandMatchResultTy
2139MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2140 switch (getLexer().getKind()) {
2141 default:
2142 return MatchOperand_NoMatch;
2143 case AsmToken::LParen:
2144 case AsmToken::Plus:
2145 case AsmToken::Minus:
2146 case AsmToken::Integer:
2147 break;
2148 }
2149
2150 const MCExpr *Expr;
2151 SMLoc S = Parser.getTok().getLoc();
2152
2153 if (getParser().parseExpression(Expr))
2154 return MatchOperand_ParseFail;
2155
2156 int64_t Val;
2157 if (!Expr->EvaluateAsAbsolute(Val)) {
2158 Error(S, "expected immediate value");
2159 return MatchOperand_ParseFail;
2160 }
2161
2162 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2163 // and because the CPU always adds one to the immediate field, the allowed
2164 // range becomes 1..4. We'll only check the range here and will deal
2165 // with the addition/subtraction when actually decoding/encoding
2166 // the instruction.
2167 if (Val < 1 || Val > 4) {
2168 Error(S, "immediate not in range (1..4)");
2169 return MatchOperand_ParseFail;
2170 }
2171
Jack Carter3b2c96e2014-01-22 23:31:38 +00002172 Operands.push_back(
2173 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002174 return MatchOperand_Success;
2175}
2176
Jack Carterdc1e35d2012-09-06 20:00:02 +00002177MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2178
Vladimir Medic4c299852013-11-06 11:27:05 +00002179 MCSymbolRefExpr::VariantKind VK =
2180 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2181 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2182 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2183 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2184 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2185 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2186 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2187 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2188 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2189 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2190 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2191 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2192 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2193 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2194 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2195 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2196 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2197 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2198 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002199
2200 return VK;
2201}
Jack Cartera63b16a2012-09-07 00:23:42 +00002202
Vladimir Medic4c299852013-11-06 11:27:05 +00002203bool MipsAsmParser::ParseInstruction(
2204 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2205 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002206 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002207 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002208 Parser.eatToEndOfStatement();
2209 return Error(NameLoc, "Unknown instruction");
2210 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002211 // First operand in MCInst is instruction mnemonic.
2212 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002213
2214 // Read the remaining operands.
2215 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2216 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002217 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002218 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002219 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002220 return Error(Loc, "unexpected token in argument list");
2221 }
2222
Jack Carterd0bd6422013-04-18 00:41:53 +00002223 while (getLexer().is(AsmToken::Comma)) {
2224 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002225 // Parse and remember the operand.
2226 if (ParseOperand(Operands, Name)) {
2227 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002228 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002229 return Error(Loc, "unexpected token in argument list");
2230 }
2231 }
2232 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002233 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2234 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002235 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002236 return Error(Loc, "unexpected token in argument list");
2237 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002238 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002239 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002240}
2241
Jack Carter0b744b32012-10-04 02:29:46 +00002242bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002243 SMLoc Loc = getLexer().getLoc();
2244 Parser.eatToEndOfStatement();
2245 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002246}
2247
2248bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002249 // Line should look like: ".set noat".
2250 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002251 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002252 // eat noat
2253 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002254 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002255 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2256 reportParseError("unexpected token in statement");
2257 return false;
2258 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002259 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002260 return false;
2261}
Jack Carterd0bd6422013-04-18 00:41:53 +00002262
Jack Carter0b744b32012-10-04 02:29:46 +00002263bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002264 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002265 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002266 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002267 getParser().Lex();
2268 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002269 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002270 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002271 return false;
2272 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002273 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002274 if (getLexer().isNot(AsmToken::Dollar)) {
2275 reportParseError("unexpected token in statement");
2276 return false;
2277 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002278 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002279 const AsmToken &Reg = Parser.getTok();
2280 if (Reg.is(AsmToken::Identifier)) {
2281 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2282 } else if (Reg.is(AsmToken::Integer)) {
2283 AtRegNo = Reg.getIntVal();
2284 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002285 reportParseError("unexpected token in statement");
2286 return false;
2287 }
Jack Carter1ac53222013-02-20 23:11:17 +00002288
Jack Carterd0bd6422013-04-18 00:41:53 +00002289 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002290 reportParseError("unexpected token in statement");
2291 return false;
2292 }
2293
2294 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002295 reportParseError("unexpected token in statement");
2296 return false;
2297 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002298 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002299
2300 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2301 reportParseError("unexpected token in statement");
2302 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002303 }
2304 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002305 return false;
2306 } else {
2307 reportParseError("unexpected token in statement");
2308 return false;
2309 }
2310}
2311
2312bool MipsAsmParser::parseSetReorderDirective() {
2313 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002314 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002315 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2316 reportParseError("unexpected token in statement");
2317 return false;
2318 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002319 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002320 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002321 return false;
2322}
2323
2324bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002325 Parser.Lex();
2326 // If this is not the end of the statement, report an error.
2327 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2328 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002329 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002330 }
2331 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002332 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002333 Parser.Lex(); // Consume the EndOfStatement.
2334 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002335}
2336
2337bool MipsAsmParser::parseSetMacroDirective() {
2338 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002339 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002340 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2341 reportParseError("unexpected token in statement");
2342 return false;
2343 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002344 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002345 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002346 return false;
2347}
2348
2349bool MipsAsmParser::parseSetNoMacroDirective() {
2350 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002351 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002352 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2353 reportParseError("`noreorder' must be set before `nomacro'");
2354 return false;
2355 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002356 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002357 reportParseError("`noreorder' must be set before `nomacro'");
2358 return false;
2359 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002360 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002361 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002362 return false;
2363}
Jack Carterd76b2372013-03-21 21:44:16 +00002364
Jack Carter39536722014-01-22 23:08:42 +00002365bool MipsAsmParser::parseSetMips16Directive() {
2366 Parser.Lex();
2367 // If this is not the end of the statement, report an error.
2368 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2369 reportParseError("unexpected token in statement");
2370 return false;
2371 }
Rafael Espindolae7583752014-01-24 16:13:20 +00002372 getTargetStreamer().emitDirectiveSetMips16();
Jack Carter39536722014-01-22 23:08:42 +00002373 Parser.Lex(); // Consume the EndOfStatement.
2374 return false;
2375}
2376
2377bool MipsAsmParser::parseSetNoMips16Directive() {
2378 Parser.Lex();
2379 // If this is not the end of the statement, report an error.
2380 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2381 reportParseError("unexpected token in statement");
2382 return false;
2383 }
2384 // For now do nothing.
2385 Parser.Lex(); // Consume the EndOfStatement.
2386 return false;
2387}
2388
Jack Carterd76b2372013-03-21 21:44:16 +00002389bool MipsAsmParser::parseSetAssignment() {
2390 StringRef Name;
2391 const MCExpr *Value;
2392
2393 if (Parser.parseIdentifier(Name))
2394 reportParseError("expected identifier after .set");
2395
2396 if (getLexer().isNot(AsmToken::Comma))
2397 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002398 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002399
Jack Carter3b2c96e2014-01-22 23:31:38 +00002400 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002401 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002402
Jack Carterd0bd6422013-04-18 00:41:53 +00002403 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002404 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002405 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002406 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002407 Sym = getContext().GetOrCreateSymbol(Name);
2408 Sym->setVariableValue(Value);
2409
2410 return false;
2411}
Jack Carterd0bd6422013-04-18 00:41:53 +00002412
Jack Carter0b744b32012-10-04 02:29:46 +00002413bool MipsAsmParser::parseDirectiveSet() {
2414
Jack Carterd0bd6422013-04-18 00:41:53 +00002415 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002416 const AsmToken &Tok = Parser.getTok();
2417
2418 if (Tok.getString() == "noat") {
2419 return parseSetNoAtDirective();
2420 } else if (Tok.getString() == "at") {
2421 return parseSetAtDirective();
2422 } else if (Tok.getString() == "reorder") {
2423 return parseSetReorderDirective();
2424 } else if (Tok.getString() == "noreorder") {
2425 return parseSetNoReorderDirective();
2426 } else if (Tok.getString() == "macro") {
2427 return parseSetMacroDirective();
2428 } else if (Tok.getString() == "nomacro") {
2429 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002430 } else if (Tok.getString() == "mips16") {
2431 return parseSetMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002432 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002433 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002434 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002435 getTargetStreamer().emitDirectiveSetNoMicroMips();
2436 Parser.eatToEndOfStatement();
2437 return false;
2438 } else if (Tok.getString() == "micromips") {
2439 getTargetStreamer().emitDirectiveSetMicroMips();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002440 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002441 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002442 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002443 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002444 parseSetAssignment();
2445 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002446 }
Jack Carter07c818d2013-01-25 01:31:34 +00002447
Jack Carter0b744b32012-10-04 02:29:46 +00002448 return true;
2449}
2450
Jack Carter07c818d2013-01-25 01:31:34 +00002451/// parseDirectiveWord
2452/// ::= .word [ expression (, expression)* ]
2453bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2454 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2455 for (;;) {
2456 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002457 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002458 return true;
2459
2460 getParser().getStreamer().EmitValue(Value, Size);
2461
2462 if (getLexer().is(AsmToken::EndOfStatement))
2463 break;
2464
2465 // FIXME: Improve diagnostic.
2466 if (getLexer().isNot(AsmToken::Comma))
2467 return Error(L, "unexpected token in directive");
2468 Parser.Lex();
2469 }
2470 }
2471
2472 Parser.Lex();
2473 return false;
2474}
2475
Vladimir Medic4c299852013-11-06 11:27:05 +00002476/// parseDirectiveGpWord
2477/// ::= .gpword local_sym
2478bool MipsAsmParser::parseDirectiveGpWord() {
2479 const MCExpr *Value;
2480 // EmitGPRel32Value requires an expression, so we are using base class
2481 // method to evaluate the expression.
2482 if (getParser().parseExpression(Value))
2483 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002484 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002485
Vladimir Medice10c1122013-11-13 13:18:04 +00002486 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002487 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002488 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002489 return false;
2490}
2491
Jack Carter0cd3c192014-01-06 23:27:31 +00002492bool MipsAsmParser::parseDirectiveOption() {
2493 // Get the option token.
2494 AsmToken Tok = Parser.getTok();
2495 // At the moment only identifiers are supported.
2496 if (Tok.isNot(AsmToken::Identifier)) {
2497 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2498 Parser.eatToEndOfStatement();
2499 return false;
2500 }
2501
2502 StringRef Option = Tok.getIdentifier();
2503
2504 if (Option == "pic0") {
2505 getTargetStreamer().emitDirectiveOptionPic0();
2506 Parser.Lex();
2507 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2508 Error(Parser.getTok().getLoc(),
2509 "unexpected token in .option pic0 directive");
2510 Parser.eatToEndOfStatement();
2511 }
2512 return false;
2513 }
2514
2515 // Unknown option.
2516 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2517 Parser.eatToEndOfStatement();
2518 return false;
2519}
2520
Jack Carter0b744b32012-10-04 02:29:46 +00002521bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002522 StringRef IDVal = DirectiveID.getString();
2523
Jack Carterd0bd6422013-04-18 00:41:53 +00002524 if (IDVal == ".ent") {
2525 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002526 Parser.Lex();
2527 return false;
2528 }
2529
Jack Carter07c818d2013-01-25 01:31:34 +00002530 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002531 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002532 Parser.Lex();
2533 return false;
2534 }
2535
Jack Carter07c818d2013-01-25 01:31:34 +00002536 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002537 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002538 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002539 return false;
2540 }
2541
Jack Carter07c818d2013-01-25 01:31:34 +00002542 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002543 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002544 }
2545
Jack Carter07c818d2013-01-25 01:31:34 +00002546 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002547 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002548 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002549 return false;
2550 }
2551
Jack Carter07c818d2013-01-25 01:31:34 +00002552 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002553 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002554 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002555 return false;
2556 }
2557
Jack Carter07c818d2013-01-25 01:31:34 +00002558 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002559 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002560 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002561 return false;
2562 }
2563
Jack Carter07c818d2013-01-25 01:31:34 +00002564 if (IDVal == ".word") {
2565 parseDirectiveWord(4, DirectiveID.getLoc());
2566 return false;
2567 }
2568
Jack Carter0cd3c192014-01-06 23:27:31 +00002569 if (IDVal == ".option")
2570 return parseDirectiveOption();
2571
2572 if (IDVal == ".abicalls") {
2573 getTargetStreamer().emitDirectiveAbiCalls();
2574 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2575 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2576 // Clear line
2577 Parser.eatToEndOfStatement();
2578 }
2579 return false;
2580 }
2581
Rafael Espindola870c4e92012-01-11 03:56:41 +00002582 return true;
2583}
2584
Rafael Espindola870c4e92012-01-11 03:56:41 +00002585extern "C" void LLVMInitializeMipsAsmParser() {
2586 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2587 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2588 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2589 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2590}
Jack Carterb4dbc172012-09-05 23:34:03 +00002591
2592#define GET_REGISTER_MATCHER
2593#define GET_MATCHER_IMPLEMENTATION
2594#include "MipsGenAsmMatcher.inc"