blob: e99de130779955427abeea6d67992935a3737ec7 [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()));
Rafael Espindola870c4e92012-01-11 03:56:41 +0000267 }
268
Jack Carterb4dbc172012-09-05 23:34:03 +0000269 MCAsmParser &getParser() const { return Parser; }
270 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000271};
272}
273
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000274namespace {
275
276/// MipsOperand - Instances of this class represent a parsed Mips machine
277/// instruction.
278class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000279
Jack Carter873c7242013-01-12 01:03:14 +0000280public:
281 enum RegisterKind {
282 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000283 Kind_GPR32,
284 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000285 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000286 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000287 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000288 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000289 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000290 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000291 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000292 Kind_ACC64DSP,
293 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000294 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000295 Kind_COP2,
296 Kind_MSA128BRegs,
297 Kind_MSA128HRegs,
298 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000299 Kind_MSA128DRegs,
300 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000301 };
302
303private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000304 enum KindTy {
305 k_CondCode,
306 k_CoprocNum,
307 k_Immediate,
308 k_Memory,
309 k_PostIndexRegister,
310 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000311 k_PtrReg,
Matheus Almeida779c5932013-11-18 12:32:49 +0000312 k_Token,
313 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000314 } Kind;
315
316 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000317
Eric Christopher8996c5d2013-03-15 00:42:55 +0000318 struct Token {
319 const char *Data;
320 unsigned Length;
321 };
322
323 struct RegOp {
324 unsigned RegNum;
325 RegisterKind Kind;
326 };
327
328 struct ImmOp {
329 const MCExpr *Val;
330 };
331
332 struct MemOp {
333 unsigned Base;
334 const MCExpr *Off;
335 };
336
Jack Carterb4dbc172012-09-05 23:34:03 +0000337 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000338 struct Token Tok;
339 struct RegOp Reg;
340 struct ImmOp Imm;
341 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000342 };
343
344 SMLoc StartLoc, EndLoc;
345
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000346public:
347 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000348 assert(N == 1 && "Invalid number of operands!");
349 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000350 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000351
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000352 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
353 assert(N == 1 && "Invalid number of operands!");
354 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
355 }
356
Vladimir Medic4c299852013-11-06 11:27:05 +0000357 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000358 // Add as immediate when possible. Null MCExpr = 0.
359 if (Expr == 0)
360 Inst.addOperand(MCOperand::CreateImm(0));
361 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
362 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
363 else
364 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000365 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000366
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000367 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000368 assert(N == 1 && "Invalid number of operands!");
369 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000370 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000371 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000372
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000373 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000374 assert(N == 2 && "Invalid number of operands!");
375
376 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
377
378 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000379 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000380 }
381
382 bool isReg() const { return Kind == k_Register; }
383 bool isImm() const { return Kind == k_Immediate; }
384 bool isToken() const { return Kind == k_Token; }
385 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000386 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000387 bool isInvNum() const { return Kind == k_Immediate; }
Matheus Almeida779c5932013-11-18 12:32:49 +0000388 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000389
390 StringRef getToken() const {
391 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000392 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000393 }
394
395 unsigned getReg() const {
396 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000397 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000398 }
399
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000400 unsigned getPtrReg() const {
401 assert((Kind == k_PtrReg) && "Invalid access!");
402 return Reg.RegNum;
403 }
404
Jack Carter873c7242013-01-12 01:03:14 +0000405 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000406 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000407 Reg.Kind = RegKind;
408 }
409
Jack Carterb4dbc172012-09-05 23:34:03 +0000410 const MCExpr *getImm() const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000411 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000412 return Imm.Val;
413 }
414
Jack Carterdc1e35d2012-09-06 20:00:02 +0000415 unsigned getMemBase() const {
416 assert((Kind == k_Memory) && "Invalid access!");
417 return Mem.Base;
418 }
419
420 const MCExpr *getMemOff() const {
421 assert((Kind == k_Memory) && "Invalid access!");
422 return Mem.Off;
423 }
424
Jack Carterb4dbc172012-09-05 23:34:03 +0000425 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
426 MipsOperand *Op = new MipsOperand(k_Token);
427 Op->Tok.Data = Str.data();
428 Op->Tok.Length = Str.size();
429 Op->StartLoc = S;
430 Op->EndLoc = S;
431 return Op;
432 }
433
434 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
435 MipsOperand *Op = new MipsOperand(k_Register);
436 Op->Reg.RegNum = RegNum;
437 Op->StartLoc = S;
438 Op->EndLoc = E;
439 return Op;
440 }
441
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000442 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
443 MipsOperand *Op = new MipsOperand(k_PtrReg);
444 Op->Reg.RegNum = RegNum;
445 Op->StartLoc = S;
446 Op->EndLoc = E;
447 return Op;
448 }
449
Jack Carterb4dbc172012-09-05 23:34:03 +0000450 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
451 MipsOperand *Op = new MipsOperand(k_Immediate);
452 Op->Imm.Val = Val;
453 Op->StartLoc = S;
454 Op->EndLoc = E;
455 return Op;
456 }
457
Matheus Almeida779c5932013-11-18 12:32:49 +0000458 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
459 MipsOperand *Op = new MipsOperand(k_LSAImm);
460 Op->Imm.Val = Val;
461 Op->StartLoc = S;
462 Op->EndLoc = E;
463 return Op;
464 }
465
Jack Carter3b2c96e2014-01-22 23:31:38 +0000466 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
467 SMLoc E) {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000468 MipsOperand *Op = new MipsOperand(k_Memory);
469 Op->Mem.Base = Base;
470 Op->Mem.Off = Off;
471 Op->StartLoc = S;
472 Op->EndLoc = E;
473 return Op;
474 }
475
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000476 bool isGPR32Asm() const {
477 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000478 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000479 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000480 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
481 }
482
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000483 bool isGPR64Asm() const {
484 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000485 }
Jack Carter873c7242013-01-12 01:03:14 +0000486
487 bool isHWRegsAsm() const {
488 assert((Kind == k_Register) && "Invalid access!");
489 return Reg.Kind == Kind_HWRegs;
490 }
Jack Carter873c7242013-01-12 01:03:14 +0000491
Jack Carter873c7242013-01-12 01:03:14 +0000492 bool isCCRAsm() const {
493 assert((Kind == k_Register) && "Invalid access!");
494 return Reg.Kind == Kind_CCRRegs;
495 }
496
Vladimir Medic4c299852013-11-06 11:27:05 +0000497 bool isAFGR64Asm() const {
Vladimir Medic233dd512013-06-24 10:05:34 +0000498 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
499 }
500
501 bool isFGR64Asm() const {
502 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
503 }
504
505 bool isFGR32Asm() const {
506 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
507 }
508
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000509 bool isFGRH32Asm() const {
510 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
511 }
512
Vladimir Medic643b3982013-07-30 10:12:14 +0000513 bool isFCCRegsAsm() const {
514 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
515 }
516
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000517 bool isACC64DSPAsm() const {
518 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000519 }
520
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000521 bool isLO32DSPAsm() const {
522 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
523 }
524
525 bool isHI32DSPAsm() const {
526 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
527 }
528
Vladimir Medic4c299852013-11-06 11:27:05 +0000529 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
Vladimir Medic05bcde62013-09-16 10:29:42 +0000530
Jack Carter5dc8ac92013-09-25 23:50:44 +0000531 bool isMSA128BAsm() const {
532 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
533 }
534
535 bool isMSA128HAsm() const {
536 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
537 }
538
539 bool isMSA128WAsm() const {
540 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
541 }
542
543 bool isMSA128DAsm() const {
544 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
545 }
546
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000547 bool isMSA128CRAsm() const {
548 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
549 }
550
Jack Carterb4dbc172012-09-05 23:34:03 +0000551 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000552 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000553 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000554 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000555
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000556 virtual void print(raw_ostream &OS) const {
557 llvm_unreachable("unimplemented!");
558 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000559}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000560} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000561
Jack Carter9e65aa32013-03-22 00:05:30 +0000562namespace llvm {
563extern const MCInstrDesc MipsInsts[];
564}
565static const MCInstrDesc &getInstDesc(unsigned Opcode) {
566 return MipsInsts[Opcode];
567}
568
569bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000570 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000571 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
572 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000573
574 if (MCID.isBranch() || MCID.isCall()) {
575 const unsigned Opcode = Inst.getOpcode();
576 MCOperand Offset;
577
578 switch (Opcode) {
579 default:
580 break;
581 case Mips::BEQ:
582 case Mips::BNE:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000583 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000584 Offset = Inst.getOperand(2);
585 if (!Offset.isImm())
586 break; // We'll deal with this situation later on when applying fixups.
587 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
588 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000589 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000590 return Error(IDLoc, "branch to misaligned address");
591 break;
592 case Mips::BGEZ:
593 case Mips::BGTZ:
594 case Mips::BLEZ:
595 case Mips::BLTZ:
596 case Mips::BGEZAL:
597 case Mips::BLTZAL:
598 case Mips::BC1F:
599 case Mips::BC1T:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000600 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000601 Offset = Inst.getOperand(1);
602 if (!Offset.isImm())
603 break; // We'll deal with this situation later on when applying fixups.
604 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
605 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000606 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000607 return Error(IDLoc, "branch to misaligned address");
608 break;
609 }
610 }
611
Jack Carterc15c1d22013-04-25 23:31:35 +0000612 if (MCID.hasDelaySlot() && Options.isReorder()) {
613 // If this instruction has a delay slot and .set reorder is active,
614 // emit a NOP after it.
615 Instructions.push_back(Inst);
616 MCInst NopInst;
617 NopInst.setOpcode(Mips::SLL);
618 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
619 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
620 NopInst.addOperand(MCOperand::CreateImm(0));
621 Instructions.push_back(NopInst);
622 return false;
623 }
624
Jack Carter9e65aa32013-03-22 00:05:30 +0000625 if (MCID.mayLoad() || MCID.mayStore()) {
626 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000627 // reference or immediate we may have to expand instructions.
628 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000629 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000630 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
631 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000632 MCOperand &Op = Inst.getOperand(i);
633 if (Op.isImm()) {
634 int MemOffset = Op.getImm();
635 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000636 // Offset can't exceed 16bit value.
637 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000638 return false;
639 }
640 } else if (Op.isExpr()) {
641 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000642 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000643 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000644 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000645 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000646 // Expand symbol.
647 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000648 return false;
649 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000650 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000651 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000652 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000653 }
654 }
655 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000656 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000657 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000658
659 if (needsExpansion(Inst))
660 expandInstruction(Inst, IDLoc, Instructions);
661 else
662 Instructions.push_back(Inst);
663
664 return false;
665}
666
Jack Carter30a59822012-10-04 04:03:53 +0000667bool MipsAsmParser::needsExpansion(MCInst &Inst) {
668
Jack Carterd0bd6422013-04-18 00:41:53 +0000669 switch (Inst.getOpcode()) {
670 case Mips::LoadImm32Reg:
671 case Mips::LoadAddr32Imm:
672 case Mips::LoadAddr32Reg:
673 return true;
674 default:
675 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000676 }
677}
Jack Carter92995f12012-10-06 00:53:28 +0000678
Jack Carter30a59822012-10-04 04:03:53 +0000679void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000680 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000681 switch (Inst.getOpcode()) {
682 case Mips::LoadImm32Reg:
683 return expandLoadImm(Inst, IDLoc, Instructions);
684 case Mips::LoadAddr32Imm:
685 return expandLoadAddressImm(Inst, IDLoc, Instructions);
686 case Mips::LoadAddr32Reg:
687 return expandLoadAddressReg(Inst, IDLoc, Instructions);
688 }
Jack Carter30a59822012-10-04 04:03:53 +0000689}
Jack Carter92995f12012-10-06 00:53:28 +0000690
Jack Carter30a59822012-10-04 04:03:53 +0000691void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000692 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000693 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000694 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000695 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000696 const MCOperand &RegOp = Inst.getOperand(0);
697 assert(RegOp.isReg() && "expected register operand kind");
698
699 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000700 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000701 if (0 <= ImmValue && ImmValue <= 65535) {
702 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000703 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000704 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000705 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000706 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000707 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000708 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000709 } else if (ImmValue < 0 && ImmValue >= -32768) {
710 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000711 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000712 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000713 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000714 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000715 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000716 Instructions.push_back(tmpInst);
717 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000718 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000719 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000720 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000721 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000722 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
723 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000724 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000725 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000726 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000727 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
728 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
729 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
730 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000731 Instructions.push_back(tmpInst);
732 }
733}
Jack Carter92995f12012-10-06 00:53:28 +0000734
Vladimir Medic4c299852013-11-06 11:27:05 +0000735void
736MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
737 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000738 MCInst tmpInst;
739 const MCOperand &ImmOp = Inst.getOperand(2);
740 assert(ImmOp.isImm() && "expected immediate operand kind");
741 const MCOperand &SrcRegOp = Inst.getOperand(1);
742 assert(SrcRegOp.isReg() && "expected register operand kind");
743 const MCOperand &DstRegOp = Inst.getOperand(0);
744 assert(DstRegOp.isReg() && "expected register operand kind");
745 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000746 if (-32768 <= ImmValue && ImmValue <= 65535) {
747 // For -32768 <= j <= 65535.
748 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000749 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000750 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
751 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
752 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
753 Instructions.push_back(tmpInst);
754 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000755 // For any other value of j that is representable as a 32-bit integer.
756 // la d,j(s) => lui d,hi16(j)
757 // ori d,d,lo16(j)
758 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000759 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000760 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
761 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
762 Instructions.push_back(tmpInst);
763 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000764 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000765 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
766 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
767 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
768 Instructions.push_back(tmpInst);
769 tmpInst.clear();
770 tmpInst.setOpcode(Mips::ADDu);
771 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
772 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
773 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
774 Instructions.push_back(tmpInst);
775 }
776}
777
Vladimir Medic4c299852013-11-06 11:27:05 +0000778void
779MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
780 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000781 MCInst tmpInst;
782 const MCOperand &ImmOp = Inst.getOperand(1);
783 assert(ImmOp.isImm() && "expected immediate operand kind");
784 const MCOperand &RegOp = Inst.getOperand(0);
785 assert(RegOp.isReg() && "expected register operand kind");
786 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000787 if (-32768 <= ImmValue && ImmValue <= 65535) {
788 // For -32768 <= j <= 65535.
789 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000790 tmpInst.setOpcode(Mips::ADDiu);
791 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000792 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000793 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
794 Instructions.push_back(tmpInst);
795 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000796 // For any other value of j that is representable as a 32-bit integer.
797 // la d,j => lui d,hi16(j)
798 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000799 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000800 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
801 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
802 Instructions.push_back(tmpInst);
803 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000804 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000805 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
806 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
807 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
808 Instructions.push_back(tmpInst);
809 }
810}
811
Jack Carter9e65aa32013-03-22 00:05:30 +0000812void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000813 SmallVectorImpl<MCInst> &Instructions,
814 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000815 const MCSymbolRefExpr *SR;
816 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000817 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000818 const MCExpr *ExprOffset;
819 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000820 unsigned AtRegNum = getReg(
821 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000822 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000823 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
824 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000825 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000826 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
827 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000828 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000829 if (isImmOpnd) {
830 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
831 ImmOffset = Inst.getOperand(2).getImm();
832 LoOffset = ImmOffset & 0x0000ffff;
833 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000834 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000835 if (LoOffset & 0x8000)
836 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000837 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000838 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000839 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000840 TempInst.setLoc(IDLoc);
841 // 1st instruction in expansion is LUi. For load instruction we can use
842 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000843 // but for stores we must use $at.
844 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000845 TempInst.setOpcode(Mips::LUi);
846 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
847 if (isImmOpnd)
848 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
849 else {
850 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000851 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000852 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
853 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
854 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000855 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000856 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000857 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000858 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000859 }
860 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000861 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000862 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000863 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000864 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000865 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000866 TempInst.setOpcode(Mips::ADDu);
867 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
868 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
869 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
870 Instructions.push_back(TempInst);
871 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +0000872 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000873 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000874 TempInst.setOpcode(Inst.getOpcode());
875 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
876 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
877 if (isImmOpnd)
878 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
879 else {
880 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000881 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
882 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
883 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000884 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000885 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000886 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000887 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000888 }
889 }
890 Instructions.push_back(TempInst);
891 TempInst.clear();
892}
893
Vladimir Medic4c299852013-11-06 11:27:05 +0000894bool MipsAsmParser::MatchAndEmitInstruction(
895 SMLoc IDLoc, unsigned &Opcode,
896 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
897 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000898 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000899 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000900 unsigned MatchResult =
901 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000902
903 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000904 default:
905 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000906 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000908 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000909 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +0000910 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +0000911 return false;
912 }
913 case Match_MissingFeature:
914 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
915 return true;
916 case Match_InvalidOperand: {
917 SMLoc ErrorLoc = IDLoc;
918 if (ErrorInfo != ~0U) {
919 if (ErrorInfo >= Operands.size())
920 return Error(IDLoc, "too few operands for instruction");
921
Vladimir Medic4c299852013-11-06 11:27:05 +0000922 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000923 if (ErrorLoc == SMLoc())
924 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000925 }
926
927 return Error(ErrorLoc, "invalid operand for instruction");
928 }
929 case Match_MnemonicFail:
930 return Error(IDLoc, "invalid instruction");
931 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000932 return true;
933}
934
Jack Carter1ac53222013-02-20 23:11:17 +0000935int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000936 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +0000937
938 if (Name == "at")
939 return getATReg();
940
Vladimir Medic4c299852013-11-06 11:27:05 +0000941 CC = StringSwitch<unsigned>(Name)
942 .Case("zero", 0)
943 .Case("a0", 4)
944 .Case("a1", 5)
945 .Case("a2", 6)
946 .Case("a3", 7)
947 .Case("v0", 2)
948 .Case("v1", 3)
949 .Case("s0", 16)
950 .Case("s1", 17)
951 .Case("s2", 18)
952 .Case("s3", 19)
953 .Case("s4", 20)
954 .Case("s5", 21)
955 .Case("s6", 22)
956 .Case("s7", 23)
957 .Case("k0", 26)
958 .Case("k1", 27)
959 .Case("sp", 29)
960 .Case("fp", 30)
961 .Case("gp", 28)
962 .Case("ra", 31)
963 .Case("t0", 8)
964 .Case("t1", 9)
965 .Case("t2", 10)
966 .Case("t3", 11)
967 .Case("t4", 12)
968 .Case("t5", 13)
969 .Case("t6", 14)
970 .Case("t7", 15)
971 .Case("t8", 24)
972 .Case("t9", 25)
973 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000974
Jack Carterd0bd6422013-04-18 00:41:53 +0000975 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +0000976 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
977 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +0000978 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +0000979 CC += 4;
980
981 if (CC == -1 && isMips64())
982 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +0000983 .Case("a4", 8)
984 .Case("a5", 9)
985 .Case("a6", 10)
986 .Case("a7", 11)
987 .Case("kt0", 26)
988 .Case("kt1", 27)
989 .Case("s8", 30)
990 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +0000991
992 return CC;
993}
Jack Carterd0bd6422013-04-18 00:41:53 +0000994
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000995int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000996
Jack Cartera63b16a2012-09-07 00:23:42 +0000997 if (Name[0] == 'f') {
998 StringRef NumString = Name.substr(1);
999 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001000 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001001 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001002 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001003 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001004 return IntVal;
1005 }
1006 return -1;
1007}
Jack Cartera63b16a2012-09-07 00:23:42 +00001008
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001009int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1010
1011 if (Name.startswith("fcc")) {
1012 StringRef NumString = Name.substr(3);
1013 unsigned IntVal;
1014 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001015 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001016 if (IntVal > 7) // There are only 8 fcc registers.
1017 return -1;
1018 return IntVal;
1019 }
1020 return -1;
1021}
1022
1023int MipsAsmParser::matchACRegisterName(StringRef Name) {
1024
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001025 if (Name.startswith("ac")) {
1026 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001027 unsigned IntVal;
1028 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001029 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001030 if (IntVal > 3) // There are only 3 acc registers.
1031 return -1;
1032 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001033 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001034 return -1;
1035}
Jack Carterd0bd6422013-04-18 00:41:53 +00001036
Jack Carter5dc8ac92013-09-25 23:50:44 +00001037int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1038 unsigned IntVal;
1039
1040 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1041 return -1;
1042
1043 if (IntVal > 31)
1044 return -1;
1045
1046 return IntVal;
1047}
1048
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001049int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1050 int CC;
1051
1052 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001053 .Case("msair", 0)
1054 .Case("msacsr", 1)
1055 .Case("msaaccess", 2)
1056 .Case("msasave", 3)
1057 .Case("msamodify", 4)
1058 .Case("msarequest", 5)
1059 .Case("msamap", 6)
1060 .Case("msaunmap", 7)
1061 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001062
1063 return CC;
1064}
1065
Vladimir Medic8cd17102013-06-20 11:21:49 +00001066int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1067
Vladimir Medic8cd17102013-06-20 11:21:49 +00001068 int CC;
1069 CC = matchCPURegisterName(Name);
1070 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001071 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1072 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001073 CC = matchFPURegisterName(Name);
Vladimir Medic4c299852013-11-06 11:27:05 +00001074 // TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001075 if (CC != -1)
1076 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1077 : Mips::FGR32RegClassID);
1078 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001079}
1080
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001081int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001082
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001083 switch (RegKind) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001084 case MipsOperand::Kind_GPR32:
1085 return Mips::GPR32RegClassID;
1086 case MipsOperand::Kind_GPR64:
1087 return Mips::GPR64RegClassID;
1088 case MipsOperand::Kind_HWRegs:
1089 return Mips::HWRegsRegClassID;
1090 case MipsOperand::Kind_FGR32Regs:
1091 return Mips::FGR32RegClassID;
1092 case MipsOperand::Kind_FGRH32Regs:
1093 return Mips::FGRH32RegClassID;
1094 case MipsOperand::Kind_FGR64Regs:
1095 return Mips::FGR64RegClassID;
1096 case MipsOperand::Kind_AFGR64Regs:
1097 return Mips::AFGR64RegClassID;
1098 case MipsOperand::Kind_CCRRegs:
1099 return Mips::CCRRegClassID;
1100 case MipsOperand::Kind_ACC64DSP:
1101 return Mips::ACC64DSPRegClassID;
1102 case MipsOperand::Kind_FCCRegs:
1103 return Mips::FCCRegClassID;
1104 case MipsOperand::Kind_MSA128BRegs:
1105 return Mips::MSA128BRegClassID;
1106 case MipsOperand::Kind_MSA128HRegs:
1107 return Mips::MSA128HRegClassID;
1108 case MipsOperand::Kind_MSA128WRegs:
1109 return Mips::MSA128WRegClassID;
1110 case MipsOperand::Kind_MSA128DRegs:
1111 return Mips::MSA128DRegClassID;
1112 case MipsOperand::Kind_MSA128CtrlRegs:
1113 return Mips::MSACtrlRegClassID;
1114 default:
1115 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001116 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001117}
Jack Carterb4dbc172012-09-05 23:34:03 +00001118
Jack Carter0b744b32012-10-04 02:29:46 +00001119bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1120 if (Reg > 31)
1121 return false;
1122
1123 aTReg = Reg;
1124 return true;
1125}
1126
Vladimir Medic4c299852013-11-06 11:27:05 +00001127int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
Jack Carter0b744b32012-10-04 02:29:46 +00001128
Jack Carterd0bd6422013-04-18 00:41:53 +00001129unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001130 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001131}
1132
Jack Carter873c7242013-01-12 01:03:14 +00001133int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001134 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001135 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001136 return -1;
1137
Jack Carter873c7242013-01-12 01:03:14 +00001138 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001139}
1140
Jack Carter873c7242013-01-12 01:03:14 +00001141int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001142 const AsmToken &Tok = Parser.getTok();
1143 int RegNum = -1;
1144
1145 if (Tok.is(AsmToken::Identifier)) {
1146 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001147 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001148 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001149 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001150 is64BitReg ? Mips::GPR64RegClassID
1151 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001152 return RegNum;
1153}
1154
Jack Carterd0bd6422013-04-18 00:41:53 +00001155bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001156 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001157
1158 SMLoc S = Parser.getTok().getLoc();
1159 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001160
Jack Carter873c7242013-01-12 01:03:14 +00001161 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001162 if (RegNo == -1)
1163 return true;
1164
Vladimir Medic4c299852013-11-06 11:27:05 +00001165 Operands.push_back(
1166 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001167 Parser.Lex(); // Eat register token.
1168 return false;
1169}
1170
Vladimir Medic4c299852013-11-06 11:27:05 +00001171bool
1172MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1173 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001174 // Check if the current operand has a custom associated parser, if so, try to
1175 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001176 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1177 if (ResTy == MatchOperand_Success)
1178 return false;
1179 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1180 // there was a match, but an error occurred, in which case, just return that
1181 // the operand parsing failed.
1182 if (ResTy == MatchOperand_ParseFail)
1183 return true;
1184
1185 switch (getLexer().getKind()) {
1186 default:
1187 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1188 return true;
1189 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001190 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001191 SMLoc S = Parser.getTok().getLoc();
1192 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001193 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001194 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001195 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001196 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001197 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001198 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001199 if (getLexer().isNot(AsmToken::Dollar))
1200 return true;
1201
Jack Carterd0bd6422013-04-18 00:41:53 +00001202 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001203 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001204 return true;
1205
1206 if (!getLexer().is(AsmToken::RParen))
1207 return true;
1208
1209 S = Parser.getTok().getLoc();
1210 Operands.push_back(MipsOperand::CreateToken(")", S));
1211 Parser.Lex();
1212 }
1213 return false;
1214 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001215 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001216 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001217 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001218 return true;
1219
Jack Carter873c7242013-01-12 01:03:14 +00001220 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001221 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001222 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001223 const MCExpr *Res =
1224 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001225
1226 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1227 return false;
1228 }
1229 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001230 // For instruction aliases like "bc1f $Label" dedicated parser will
1231 // eat the '$' sign before failing. So in order to look for appropriate
1232 // label we must check first if we have already consumed '$'.
1233 if (hasConsumedDollar) {
1234 hasConsumedDollar = false;
1235 SMLoc S = Parser.getTok().getLoc();
1236 StringRef Identifier;
1237 if (Parser.parseIdentifier(Identifier))
1238 return true;
1239 SMLoc E =
1240 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1241 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1242 // Create a symbol reference.
1243 const MCExpr *Res =
1244 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1245
1246 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1247 return false;
1248 }
Jack Carterd76b2372013-03-21 21:44:16 +00001249 // Look for the existing symbol, we should check if
Matheus Almeidad534fc32014-01-30 13:40:26 +00001250 // we need to assign the proper RegisterKind.
Jack Carterd0bd6422013-04-18 00:41:53 +00001251 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1252 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001253 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001254 case AsmToken::LParen:
1255 case AsmToken::Minus:
1256 case AsmToken::Plus:
1257 case AsmToken::Integer:
1258 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001259 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001260 const MCExpr *IdVal;
1261 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001262 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001263 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001264 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001265 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1266 return false;
1267 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001268 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001269 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001270 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001271 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001272 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001273 return true;
1274
Jack Carter873c7242013-01-12 01:03:14 +00001275 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1276
Jack Carterdc1e35d2012-09-06 20:00:02 +00001277 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1278 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001279 } // case AsmToken::Percent
1280 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001281 return true;
1282}
1283
Vladimir Medic4c299852013-11-06 11:27:05 +00001284const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001285 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001286 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001287 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001288 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001289 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001290 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001291 short Val = MCE->getValue();
1292 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001293 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001294 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001295 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001296 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001297 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001298 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001299 if (LoSign)
1300 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001301 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001302 } else {
1303 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001304 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001305 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001306 }
1307
Jack Carterb5cf5902013-04-17 00:18:04 +00001308 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001309 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001310 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001311 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001312 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001313 return Res;
1314 }
1315
1316 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001317 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1318
1319 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1320 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1321 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1322 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1323 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1324 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1325 return MipsMCExpr::CreateHi(Expr, getContext());
1326 return MipsMCExpr::CreateLo(Expr, getContext());
1327 }
1328
Jack Carterd0bd6422013-04-18 00:41:53 +00001329 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1330 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001331 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1332 return Res;
1333 }
1334
1335 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001336 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1337 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1338 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001339 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001340 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001341 return Expr;
1342}
1343
1344bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1345
1346 switch (Expr->getKind()) {
1347 case MCExpr::Constant:
1348 return true;
1349 case MCExpr::SymbolRef:
1350 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1351 case MCExpr::Binary:
1352 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1353 if (!isEvaluated(BE->getLHS()))
1354 return false;
1355 return isEvaluated(BE->getRHS());
1356 }
1357 case MCExpr::Unary:
1358 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001359 case MCExpr::Target:
1360 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001361 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001362 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001363}
Jack Carterd0bd6422013-04-18 00:41:53 +00001364
Jack Carterb5cf5902013-04-17 00:18:04 +00001365bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001366 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001367 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001368 if (Tok.isNot(AsmToken::Identifier))
1369 return true;
1370
1371 std::string Str = Tok.getIdentifier().str();
1372
Jack Carterd0bd6422013-04-18 00:41:53 +00001373 Parser.Lex(); // Eat the identifier.
1374 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001375 const MCExpr *IdVal;
1376 SMLoc EndLoc;
1377
1378 if (getLexer().getKind() == AsmToken::LParen) {
1379 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001380 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001381 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001382 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001383 const AsmToken &nextTok = Parser.getTok();
1384 if (nextTok.isNot(AsmToken::Identifier))
1385 return true;
1386 Str += "(%";
1387 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001388 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001389 if (getLexer().getKind() != AsmToken::LParen)
1390 return true;
1391 } else
1392 break;
1393 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001394 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001395 return true;
1396
1397 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001398 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001399
1400 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001401 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001402
Jack Carterd0bd6422013-04-18 00:41:53 +00001403 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001404 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001405}
1406
Jack Carterb4dbc172012-09-05 23:34:03 +00001407bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1408 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001409 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001410 RegNo = tryParseRegister(isMips64());
1411 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001412 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001413}
1414
Jack Carterb5cf5902013-04-17 00:18:04 +00001415bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001416 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001417 bool Result = true;
1418
1419 while (getLexer().getKind() == AsmToken::LParen)
1420 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001421
Jack Carterd0bd6422013-04-18 00:41:53 +00001422 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001423 default:
1424 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001425 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001426 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001427 case AsmToken::Integer:
1428 case AsmToken::Minus:
1429 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001430 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001431 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001432 else
1433 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001434 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001435 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001436 break;
Jack Carter873c7242013-01-12 01:03:14 +00001437 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001438 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001439 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001440 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001441}
1442
Jack Carterb4dbc172012-09-05 23:34:03 +00001443MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001444 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001445
1446 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001447 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001448 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001449 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001450 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001451 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001452
Jack Carterb5cf5902013-04-17 00:18:04 +00001453 if (getLexer().getKind() == AsmToken::LParen) {
1454 Parser.Lex();
1455 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001456 }
1457
Jack Carterb5cf5902013-04-17 00:18:04 +00001458 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001459 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001460 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001461
Jack Carterd0bd6422013-04-18 00:41:53 +00001462 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001463 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001464 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001465 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001466 SMLoc E =
1467 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001468 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1469 return MatchOperand_Success;
1470 }
1471 if (Tok.is(AsmToken::EndOfStatement)) {
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
Jack Carterd0bd6422013-04-18 00:41:53 +00001475 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001476 Operands.push_back(MipsOperand::CreateMem(
1477 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001478 return MatchOperand_Success;
1479 }
1480 Error(Parser.getTok().getLoc(), "'(' expected");
1481 return MatchOperand_ParseFail;
1482 }
1483
Jack Carterd0bd6422013-04-18 00:41:53 +00001484 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001485 }
1486
Vladimir Medic4c299852013-11-06 11:27:05 +00001487 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1488 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001489 if (Res != MatchOperand_Success)
1490 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001491
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001492 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001493 Error(Parser.getTok().getLoc(), "')' expected");
1494 return MatchOperand_ParseFail;
1495 }
1496
Jack Carter873c7242013-01-12 01:03:14 +00001497 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1498
Jack Carterd0bd6422013-04-18 00:41:53 +00001499 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001500
1501 if (IdVal == 0)
1502 IdVal = MCConstantExpr::Create(0, getContext());
1503
Jack Carterd0bd6422013-04-18 00:41:53 +00001504 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001505 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001506 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001507 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001508 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001509 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001510 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1511 int64_t Imm;
1512 if (IdVal->EvaluateAsAbsolute(Imm))
1513 IdVal = MCConstantExpr::Create(Imm, getContext());
1514 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1515 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1516 getContext());
1517 }
1518
Jack Carterdc1e35d2012-09-06 20:00:02 +00001519 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1520 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001521 return MatchOperand_Success;
1522}
1523
Vladimir Medic4c299852013-11-06 11:27:05 +00001524bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1525 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001526 // If the first token is not '$' we have an error.
1527 if (Parser.getTok().isNot(AsmToken::Dollar))
1528 return false;
1529
1530 SMLoc S = Parser.getTok().getLoc();
1531 Parser.Lex();
1532 AsmToken::TokenKind TkKind = getLexer().getKind();
1533 int Reg;
1534
1535 if (TkKind == AsmToken::Integer) {
1536 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1537 regKindToRegClass(RegKind));
1538 if (Reg == -1)
1539 return false;
1540 } else if (TkKind == AsmToken::Identifier) {
1541 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1542 return false;
1543 Reg = getReg(regKindToRegClass(RegKind), Reg);
1544 } else {
1545 return false;
1546 }
1547
1548 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1549 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1550 Operands.push_back(Op);
1551 Parser.Lex();
1552 return true;
1553}
1554
1555MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001556MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1557 MipsOperand::RegisterKind RegKind =
1558 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001559
1560 // Parse index register.
1561 if (!parsePtrReg(Operands, RegKind))
1562 return MatchOperand_NoMatch;
1563
1564 // Parse '('.
1565 if (Parser.getTok().isNot(AsmToken::LParen))
1566 return MatchOperand_NoMatch;
1567
1568 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1569 Parser.Lex();
1570
1571 // Parse base register.
1572 if (!parsePtrReg(Operands, RegKind))
1573 return MatchOperand_NoMatch;
1574
1575 // Parse ')'.
1576 if (Parser.getTok().isNot(AsmToken::RParen))
1577 return MatchOperand_NoMatch;
1578
1579 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1580 Parser.Lex();
1581
1582 return MatchOperand_Success;
1583}
1584
Jack Carter873c7242013-01-12 01:03:14 +00001585MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001586MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001587 int RegKind) {
1588 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001589 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001590 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001591 return MatchOperand_Success;
1592 return MatchOperand_NoMatch;
1593 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001594 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001595 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001596 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001597 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001598 if (!hasConsumedDollar) {
1599 Parser.Lex(); // Eat the '$'
1600 hasConsumedDollar = true;
1601 }
1602 if (getLexer().getKind() == AsmToken::Identifier) {
1603 int RegNum = -1;
1604 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001605 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001606 switch (RegKind) {
1607 case MipsOperand::Kind_GPR32:
1608 case MipsOperand::Kind_GPR64:
1609 RegNum = matchCPURegisterName(RegName);
1610 break;
1611 case MipsOperand::Kind_AFGR64Regs:
1612 case MipsOperand::Kind_FGR64Regs:
1613 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001614 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001615 RegNum = matchFPURegisterName(RegName);
1616 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1617 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001618 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1619 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001620 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001621 break;
1622 case MipsOperand::Kind_FCCRegs:
1623 RegNum = matchFCCRegisterName(RegName);
1624 break;
1625 case MipsOperand::Kind_ACC64DSP:
1626 RegNum = matchACRegisterName(RegName);
1627 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001628 default:
1629 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001630 }
1631 // No match found, return _NoMatch to give a chance to other round.
1632 if (RegNum < 0)
1633 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001634
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001635 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1636 if (RegVal == -1)
1637 return MatchOperand_NoMatch;
1638
Vladimir Medic4c299852013-11-06 11:27:05 +00001639 MipsOperand *Op =
1640 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001641 Op->setRegKind(Kind);
1642 Operands.push_back(Op);
1643 hasConsumedDollar = false;
1644 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001645 return MatchOperand_Success;
1646 } else if (getLexer().getKind() == AsmToken::Integer) {
1647 unsigned RegNum = Parser.getTok().getIntVal();
1648 if (Kind == MipsOperand::Kind_HWRegs) {
1649 if (RegNum != 29)
1650 return MatchOperand_NoMatch;
1651 // Only hwreg 29 is supported, found at index 0.
1652 RegNum = 0;
1653 }
1654 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1655 if (Reg == -1)
1656 return MatchOperand_NoMatch;
1657 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1658 Op->setRegKind(Kind);
1659 Operands.push_back(Op);
1660 hasConsumedDollar = false;
1661 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001662 if ((RegKind == MipsOperand::Kind_GPR32) &&
1663 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001664 // Check if it is indexed addressing operand.
1665 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1666 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001667 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001668 return MatchOperand_NoMatch;
1669 if (getLexer().isNot(AsmToken::RParen))
1670 return MatchOperand_NoMatch;
1671 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1672 Parser.Lex();
1673 }
Jack Carter873c7242013-01-12 01:03:14 +00001674 return MatchOperand_Success;
1675 }
1676 return MatchOperand_NoMatch;
1677}
Vladimir Medic64828a12013-07-16 10:07:14 +00001678
Matheus Almeidab74293d2013-10-14 11:49:30 +00001679bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1680 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1681
1682 if (Val < 0)
1683 return false;
1684
1685 switch (Kind) {
1686 default:
1687 return false;
1688 case MipsOperand::Kind_MSA128BRegs:
1689 return Val < 16;
1690 case MipsOperand::Kind_MSA128HRegs:
1691 return Val < 8;
1692 case MipsOperand::Kind_MSA128WRegs:
1693 return Val < 4;
1694 case MipsOperand::Kind_MSA128DRegs:
1695 return Val < 2;
1696 }
1697}
1698
Vladimir Medic8cd17102013-06-20 11:21:49 +00001699MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001700MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001701 int RegKind) {
1702 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1703 SMLoc S = Parser.getTok().getLoc();
1704 std::string RegName;
1705
1706 if (Parser.getTok().isNot(AsmToken::Dollar))
1707 return MatchOperand_NoMatch;
1708
1709 switch (RegKind) {
1710 default:
1711 return MatchOperand_ParseFail;
1712 case MipsOperand::Kind_MSA128BRegs:
1713 case MipsOperand::Kind_MSA128HRegs:
1714 case MipsOperand::Kind_MSA128WRegs:
1715 case MipsOperand::Kind_MSA128DRegs:
1716 break;
1717 }
1718
1719 Parser.Lex(); // Eat the '$'.
1720 if (getLexer().getKind() == AsmToken::Identifier)
1721 RegName = Parser.getTok().getString().lower();
1722 else
1723 return MatchOperand_ParseFail;
1724
1725 int RegNum = matchMSA128RegisterName(RegName);
1726
1727 if (RegNum < 0 || RegNum > 31)
1728 return MatchOperand_ParseFail;
1729
1730 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1731 if (RegVal == -1)
1732 return MatchOperand_ParseFail;
1733
Vladimir Medic4c299852013-11-06 11:27:05 +00001734 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001735 Op->setRegKind(Kind);
1736 Operands.push_back(Op);
1737
1738 Parser.Lex(); // Eat the register identifier.
1739
Matheus Almeidab74293d2013-10-14 11:49:30 +00001740 // MSA registers may be suffixed with an index in the form of:
1741 // 1) Immediate expression.
1742 // 2) General Purpose Register.
1743 // Examples:
1744 // 1) copy_s.b $29,$w0[0]
1745 // 2) sld.b $w0,$w1[$1]
1746
1747 if (Parser.getTok().isNot(AsmToken::LBrac))
1748 return MatchOperand_Success;
1749
1750 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1751
1752 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1753 Parser.Lex(); // Parse the '[' token.
1754
1755 if (Parser.getTok().is(AsmToken::Dollar)) {
1756 // This must be a GPR.
1757 MipsOperand *RegOp;
1758 SMLoc VIdx = Parser.getTok().getLoc();
1759 Parser.Lex(); // Parse the '$' token.
1760
1761 // GPR have aliases and we must account for that. Example: $30 == $fp
1762 if (getLexer().getKind() == AsmToken::Integer) {
1763 unsigned RegNum = Parser.getTok().getIntVal();
1764 int Reg = matchRegisterByNumber(
1765 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1766 if (Reg == -1) {
1767 Error(VIdx, "invalid general purpose register");
1768 return MatchOperand_ParseFail;
1769 }
1770
1771 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1772 } else if (getLexer().getKind() == AsmToken::Identifier) {
1773 int RegNum = -1;
1774 std::string RegName = Parser.getTok().getString().lower();
1775
1776 RegNum = matchCPURegisterName(RegName);
1777 if (RegNum == -1) {
1778 Error(VIdx, "general purpose register expected");
1779 return MatchOperand_ParseFail;
1780 }
1781 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1782 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1783 } else
1784 return MatchOperand_ParseFail;
1785
1786 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1787 Operands.push_back(RegOp);
1788 Parser.Lex(); // Eat the register identifier.
1789
1790 if (Parser.getTok().isNot(AsmToken::RBrac))
1791 return MatchOperand_ParseFail;
1792
1793 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1794 Parser.Lex(); // Parse the ']' token.
1795
1796 return MatchOperand_Success;
1797 }
1798
1799 // The index must be a constant expression then.
1800 SMLoc VIdx = Parser.getTok().getLoc();
1801 const MCExpr *ImmVal;
1802
1803 if (getParser().parseExpression(ImmVal))
1804 return MatchOperand_ParseFail;
1805
1806 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1807 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1808 Error(VIdx, "invalid immediate value");
1809 return MatchOperand_ParseFail;
1810 }
1811
1812 SMLoc E = Parser.getTok().getEndLoc();
1813
1814 if (Parser.getTok().isNot(AsmToken::RBrac))
1815 return MatchOperand_ParseFail;
1816
Vladimir Medic4c299852013-11-06 11:27:05 +00001817 bool insve =
1818 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1819 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001820
1821 // The second vector index of insve instructions is always 0.
1822 if (insve && Operands.size() > 6) {
1823 if (expr->getValue() != 0) {
1824 Error(VIdx, "immediate value must be 0");
1825 return MatchOperand_ParseFail;
1826 }
1827 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1828 } else
1829 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1830
1831 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1832
1833 Parser.Lex(); // Parse the ']' token.
1834
Jack Carter5dc8ac92013-09-25 23:50:44 +00001835 return MatchOperand_Success;
1836}
1837
1838MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001839MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1840 int RegKind) {
1841 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1842
1843 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1844 return MatchOperand_NoMatch;
1845
1846 if (Parser.getTok().isNot(AsmToken::Dollar))
1847 return MatchOperand_ParseFail;
1848
1849 SMLoc S = Parser.getTok().getLoc();
1850
1851 Parser.Lex(); // Eat the '$' symbol.
1852
1853 int RegNum = -1;
1854 if (getLexer().getKind() == AsmToken::Identifier)
1855 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1856 else if (getLexer().getKind() == AsmToken::Integer)
1857 RegNum = Parser.getTok().getIntVal();
1858 else
1859 return MatchOperand_ParseFail;
1860
1861 if (RegNum < 0 || RegNum > 7)
1862 return MatchOperand_ParseFail;
1863
1864 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1865 if (RegVal == -1)
1866 return MatchOperand_ParseFail;
1867
Vladimir Medic4c299852013-11-06 11:27:05 +00001868 MipsOperand *RegOp =
1869 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001870 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1871 Operands.push_back(RegOp);
1872 Parser.Lex(); // Eat the register identifier.
1873
1874 return MatchOperand_Success;
1875}
1876
1877MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001878MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001879
1880 if (!isMips64())
1881 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001882 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001883}
1884
1885MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001886MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1887 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001888}
Jack Carter873c7242013-01-12 01:03:14 +00001889
Vladimir Medic4c299852013-11-06 11:27:05 +00001890MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1891 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001892
1893 if (isFP64())
1894 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001895 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001896}
1897
1898MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001899MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001900 if (!isFP64())
1901 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001902 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001903}
1904
1905MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001906MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1907 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1908}
1909
1910MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1911 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1912 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001913}
1914
Vladimir Medic643b3982013-07-30 10:12:14 +00001915MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001916MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1917 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001918}
1919
1920MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001921MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1922 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001923}
1924
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001925MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001926MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001927 // If the first token is not '$' we have an error.
1928 if (Parser.getTok().isNot(AsmToken::Dollar))
1929 return MatchOperand_NoMatch;
1930
1931 SMLoc S = Parser.getTok().getLoc();
1932 Parser.Lex(); // Eat the '$'
1933
1934 const AsmToken &Tok = Parser.getTok(); // Get next token.
1935
1936 if (Tok.isNot(AsmToken::Identifier))
1937 return MatchOperand_NoMatch;
1938
1939 if (!Tok.getIdentifier().startswith("ac"))
1940 return MatchOperand_NoMatch;
1941
1942 StringRef NumString = Tok.getIdentifier().substr(2);
1943
1944 unsigned IntVal;
1945 if (NumString.getAsInteger(10, IntVal))
1946 return MatchOperand_NoMatch;
1947
1948 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1949
1950 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1951 Op->setRegKind(MipsOperand::Kind_LO32DSP);
1952 Operands.push_back(Op);
1953
1954 Parser.Lex(); // Eat the register number.
1955 return MatchOperand_Success;
1956}
1957
1958MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001959MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001960 // If the first token is not '$' we have an error.
1961 if (Parser.getTok().isNot(AsmToken::Dollar))
1962 return MatchOperand_NoMatch;
1963
1964 SMLoc S = Parser.getTok().getLoc();
1965 Parser.Lex(); // Eat the '$'
1966
1967 const AsmToken &Tok = Parser.getTok(); // Get next token.
1968
1969 if (Tok.isNot(AsmToken::Identifier))
1970 return MatchOperand_NoMatch;
1971
1972 if (!Tok.getIdentifier().startswith("ac"))
1973 return MatchOperand_NoMatch;
1974
1975 StringRef NumString = Tok.getIdentifier().substr(2);
1976
1977 unsigned IntVal;
1978 if (NumString.getAsInteger(10, IntVal))
1979 return MatchOperand_NoMatch;
1980
1981 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1982
1983 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1984 Op->setRegKind(MipsOperand::Kind_HI32DSP);
1985 Operands.push_back(Op);
1986
1987 Parser.Lex(); // Eat the register number.
1988 return MatchOperand_Success;
1989}
1990
Vladimir Medic05bcde62013-09-16 10:29:42 +00001991MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001992MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00001993 // If the first token is not '$' we have an error.
1994 if (Parser.getTok().isNot(AsmToken::Dollar))
1995 return MatchOperand_NoMatch;
1996
1997 SMLoc S = Parser.getTok().getLoc();
1998 Parser.Lex(); // Eat the '$'
1999
2000 const AsmToken &Tok = Parser.getTok(); // Get next token.
2001
2002 if (Tok.isNot(AsmToken::Integer))
2003 return MatchOperand_NoMatch;
2004
2005 unsigned IntVal = Tok.getIntVal();
2006
2007 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2008
2009 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2010 Op->setRegKind(MipsOperand::Kind_COP2);
2011 Operands.push_back(Op);
2012
2013 Parser.Lex(); // Eat the register number.
2014 return MatchOperand_Success;
2015}
2016
Vladimir Medic4c299852013-11-06 11:27:05 +00002017MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2018 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2019 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002020}
2021
Vladimir Medic4c299852013-11-06 11:27:05 +00002022MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2023 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2024 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002025}
2026
Vladimir Medic4c299852013-11-06 11:27:05 +00002027MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2028 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2029 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002030}
2031
Vladimir Medic4c299852013-11-06 11:27:05 +00002032MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2033 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2034 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002035}
2036
Vladimir Medic4c299852013-11-06 11:27:05 +00002037MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2038 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2039 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002040}
2041
Jack Carterd0bd6422013-04-18 00:41:53 +00002042bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002043 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002044
2045 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2046 if (Sym) {
2047 SMLoc S = Parser.getTok().getLoc();
2048 const MCExpr *Expr;
2049 if (Sym->isVariable())
2050 Expr = Sym->getVariableValue();
2051 else
2052 return false;
2053 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002054 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2055 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002056 const StringRef DefSymbol = Ref->getSymbol().getName();
2057 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002058 int RegNum = -1;
2059 APInt IntVal(32, -1);
2060 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2061 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002062 isMips64() ? Mips::GPR64RegClassID
2063 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002064 else {
2065 // Lookup for the register with the corresponding name.
2066 switch (Kind) {
2067 case MipsOperand::Kind_AFGR64Regs:
2068 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002069 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002070 break;
2071 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002072 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002073 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002074 case MipsOperand::Kind_GPR64:
2075 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002076 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002077 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002078 break;
2079 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002080 if (RegNum > -1)
2081 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002082 }
Jack Carterd76b2372013-03-21 21:44:16 +00002083 if (RegNum > -1) {
2084 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002085 MipsOperand *op =
2086 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002087 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002088 Operands.push_back(op);
2089 return true;
2090 }
2091 }
2092 } else if (Expr->getKind() == MCExpr::Constant) {
2093 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002094 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2095 MipsOperand *op =
2096 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002097 Operands.push_back(op);
2098 return true;
2099 }
2100 }
2101 return false;
2102}
Jack Carterd0bd6422013-04-18 00:41:53 +00002103
Jack Carter873c7242013-01-12 01:03:14 +00002104MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002105MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2106 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002107}
2108
2109MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002110MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2111 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002112}
2113
Vladimir Medic2b953d02013-10-01 09:48:56 +00002114MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002115MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002116 const MCExpr *IdVal;
2117 // If the first token is '$' we may have register operand.
2118 if (Parser.getTok().is(AsmToken::Dollar))
2119 return MatchOperand_NoMatch;
2120 SMLoc S = Parser.getTok().getLoc();
2121 if (getParser().parseExpression(IdVal))
2122 return MatchOperand_ParseFail;
2123 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002124 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002125 int64_t Val = MCE->getValue();
2126 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2127 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002128 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002129 return MatchOperand_Success;
2130}
2131
Matheus Almeida779c5932013-11-18 12:32:49 +00002132MipsAsmParser::OperandMatchResultTy
2133MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2134 switch (getLexer().getKind()) {
2135 default:
2136 return MatchOperand_NoMatch;
2137 case AsmToken::LParen:
2138 case AsmToken::Plus:
2139 case AsmToken::Minus:
2140 case AsmToken::Integer:
2141 break;
2142 }
2143
2144 const MCExpr *Expr;
2145 SMLoc S = Parser.getTok().getLoc();
2146
2147 if (getParser().parseExpression(Expr))
2148 return MatchOperand_ParseFail;
2149
2150 int64_t Val;
2151 if (!Expr->EvaluateAsAbsolute(Val)) {
2152 Error(S, "expected immediate value");
2153 return MatchOperand_ParseFail;
2154 }
2155
2156 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2157 // and because the CPU always adds one to the immediate field, the allowed
2158 // range becomes 1..4. We'll only check the range here and will deal
2159 // with the addition/subtraction when actually decoding/encoding
2160 // the instruction.
2161 if (Val < 1 || Val > 4) {
2162 Error(S, "immediate not in range (1..4)");
2163 return MatchOperand_ParseFail;
2164 }
2165
Jack Carter3b2c96e2014-01-22 23:31:38 +00002166 Operands.push_back(
2167 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002168 return MatchOperand_Success;
2169}
2170
Jack Carterdc1e35d2012-09-06 20:00:02 +00002171MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2172
Vladimir Medic4c299852013-11-06 11:27:05 +00002173 MCSymbolRefExpr::VariantKind VK =
2174 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2175 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2176 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2177 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2178 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2179 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2180 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2181 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2182 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2183 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2184 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2185 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2186 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2187 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2188 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2189 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2190 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2191 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2192 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002193
2194 return VK;
2195}
Jack Cartera63b16a2012-09-07 00:23:42 +00002196
Vladimir Medic4c299852013-11-06 11:27:05 +00002197bool MipsAsmParser::ParseInstruction(
2198 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2199 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002200 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002201 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002202 Parser.eatToEndOfStatement();
2203 return Error(NameLoc, "Unknown instruction");
2204 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002205 // First operand in MCInst is instruction mnemonic.
2206 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002207
2208 // Read the remaining operands.
2209 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2210 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002211 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002212 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002213 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002214 return Error(Loc, "unexpected token in argument list");
2215 }
2216
Jack Carterd0bd6422013-04-18 00:41:53 +00002217 while (getLexer().is(AsmToken::Comma)) {
2218 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002219 // Parse and remember the operand.
2220 if (ParseOperand(Operands, Name)) {
2221 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002222 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002223 return Error(Loc, "unexpected token in argument list");
2224 }
2225 }
2226 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002227 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2228 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002229 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002230 return Error(Loc, "unexpected token in argument list");
2231 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002232 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002233 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002234}
2235
Jack Carter0b744b32012-10-04 02:29:46 +00002236bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002237 SMLoc Loc = getLexer().getLoc();
2238 Parser.eatToEndOfStatement();
2239 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002240}
2241
2242bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002243 // Line should look like: ".set noat".
2244 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002245 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002246 // eat noat
2247 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002248 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002249 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2250 reportParseError("unexpected token in statement");
2251 return false;
2252 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002253 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002254 return false;
2255}
Jack Carterd0bd6422013-04-18 00:41:53 +00002256
Jack Carter0b744b32012-10-04 02:29:46 +00002257bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002258 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002259 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002260 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002261 getParser().Lex();
2262 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002263 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002264 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002265 return false;
2266 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002267 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002268 if (getLexer().isNot(AsmToken::Dollar)) {
2269 reportParseError("unexpected token in statement");
2270 return false;
2271 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002272 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002273 const AsmToken &Reg = Parser.getTok();
2274 if (Reg.is(AsmToken::Identifier)) {
2275 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2276 } else if (Reg.is(AsmToken::Integer)) {
2277 AtRegNo = Reg.getIntVal();
2278 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002279 reportParseError("unexpected token in statement");
2280 return false;
2281 }
Jack Carter1ac53222013-02-20 23:11:17 +00002282
Jack Carterd0bd6422013-04-18 00:41:53 +00002283 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002284 reportParseError("unexpected token in statement");
2285 return false;
2286 }
2287
2288 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002289 reportParseError("unexpected token in statement");
2290 return false;
2291 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002292 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002293
2294 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2295 reportParseError("unexpected token in statement");
2296 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002297 }
2298 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002299 return false;
2300 } else {
2301 reportParseError("unexpected token in statement");
2302 return false;
2303 }
2304}
2305
2306bool MipsAsmParser::parseSetReorderDirective() {
2307 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002308 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002309 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2310 reportParseError("unexpected token in statement");
2311 return false;
2312 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002313 Options.setReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002314 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002315 return false;
2316}
2317
2318bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002319 Parser.Lex();
2320 // If this is not the end of the statement, report an error.
2321 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2322 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002323 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002324 }
2325 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002326 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002327 Parser.Lex(); // Consume the EndOfStatement.
2328 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002329}
2330
2331bool MipsAsmParser::parseSetMacroDirective() {
2332 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002333 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002334 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2335 reportParseError("unexpected token in statement");
2336 return false;
2337 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002338 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002339 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002340 return false;
2341}
2342
2343bool MipsAsmParser::parseSetNoMacroDirective() {
2344 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002345 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002346 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2347 reportParseError("`noreorder' must be set before `nomacro'");
2348 return false;
2349 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002350 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002351 reportParseError("`noreorder' must be set before `nomacro'");
2352 return false;
2353 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002354 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002355 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002356 return false;
2357}
Jack Carterd76b2372013-03-21 21:44:16 +00002358
Jack Carter39536722014-01-22 23:08:42 +00002359bool MipsAsmParser::parseSetMips16Directive() {
2360 Parser.Lex();
2361 // If this is not the end of the statement, report an error.
2362 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2363 reportParseError("unexpected token in statement");
2364 return false;
2365 }
Rafael Espindolae7583752014-01-24 16:13:20 +00002366 getTargetStreamer().emitDirectiveSetMips16();
Jack Carter39536722014-01-22 23:08:42 +00002367 Parser.Lex(); // Consume the EndOfStatement.
2368 return false;
2369}
2370
2371bool MipsAsmParser::parseSetNoMips16Directive() {
2372 Parser.Lex();
2373 // If this is not the end of the statement, report an error.
2374 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2375 reportParseError("unexpected token in statement");
2376 return false;
2377 }
2378 // For now do nothing.
2379 Parser.Lex(); // Consume the EndOfStatement.
2380 return false;
2381}
2382
Jack Carterd76b2372013-03-21 21:44:16 +00002383bool MipsAsmParser::parseSetAssignment() {
2384 StringRef Name;
2385 const MCExpr *Value;
2386
2387 if (Parser.parseIdentifier(Name))
2388 reportParseError("expected identifier after .set");
2389
2390 if (getLexer().isNot(AsmToken::Comma))
2391 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002392 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002393
Jack Carter3b2c96e2014-01-22 23:31:38 +00002394 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002395 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002396
Jack Carterd0bd6422013-04-18 00:41:53 +00002397 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002398 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002399 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002400 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002401 Sym = getContext().GetOrCreateSymbol(Name);
2402 Sym->setVariableValue(Value);
2403
2404 return false;
2405}
Jack Carterd0bd6422013-04-18 00:41:53 +00002406
Jack Carter0b744b32012-10-04 02:29:46 +00002407bool MipsAsmParser::parseDirectiveSet() {
2408
Jack Carterd0bd6422013-04-18 00:41:53 +00002409 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002410 const AsmToken &Tok = Parser.getTok();
2411
2412 if (Tok.getString() == "noat") {
2413 return parseSetNoAtDirective();
2414 } else if (Tok.getString() == "at") {
2415 return parseSetAtDirective();
2416 } else if (Tok.getString() == "reorder") {
2417 return parseSetReorderDirective();
2418 } else if (Tok.getString() == "noreorder") {
2419 return parseSetNoReorderDirective();
2420 } else if (Tok.getString() == "macro") {
2421 return parseSetMacroDirective();
2422 } else if (Tok.getString() == "nomacro") {
2423 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002424 } else if (Tok.getString() == "mips16") {
2425 return parseSetMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002426 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002427 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002428 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002429 getTargetStreamer().emitDirectiveSetNoMicroMips();
2430 Parser.eatToEndOfStatement();
2431 return false;
2432 } else if (Tok.getString() == "micromips") {
2433 getTargetStreamer().emitDirectiveSetMicroMips();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002434 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002435 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002436 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002437 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002438 parseSetAssignment();
2439 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002440 }
Jack Carter07c818d2013-01-25 01:31:34 +00002441
Jack Carter0b744b32012-10-04 02:29:46 +00002442 return true;
2443}
2444
Jack Carter07c818d2013-01-25 01:31:34 +00002445/// parseDirectiveWord
2446/// ::= .word [ expression (, expression)* ]
2447bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2449 for (;;) {
2450 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002451 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002452 return true;
2453
2454 getParser().getStreamer().EmitValue(Value, Size);
2455
2456 if (getLexer().is(AsmToken::EndOfStatement))
2457 break;
2458
2459 // FIXME: Improve diagnostic.
2460 if (getLexer().isNot(AsmToken::Comma))
2461 return Error(L, "unexpected token in directive");
2462 Parser.Lex();
2463 }
2464 }
2465
2466 Parser.Lex();
2467 return false;
2468}
2469
Vladimir Medic4c299852013-11-06 11:27:05 +00002470/// parseDirectiveGpWord
2471/// ::= .gpword local_sym
2472bool MipsAsmParser::parseDirectiveGpWord() {
2473 const MCExpr *Value;
2474 // EmitGPRel32Value requires an expression, so we are using base class
2475 // method to evaluate the expression.
2476 if (getParser().parseExpression(Value))
2477 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002478 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002479
Vladimir Medice10c1122013-11-13 13:18:04 +00002480 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002481 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002482 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002483 return false;
2484}
2485
Jack Carter0cd3c192014-01-06 23:27:31 +00002486bool MipsAsmParser::parseDirectiveOption() {
2487 // Get the option token.
2488 AsmToken Tok = Parser.getTok();
2489 // At the moment only identifiers are supported.
2490 if (Tok.isNot(AsmToken::Identifier)) {
2491 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2492 Parser.eatToEndOfStatement();
2493 return false;
2494 }
2495
2496 StringRef Option = Tok.getIdentifier();
2497
2498 if (Option == "pic0") {
2499 getTargetStreamer().emitDirectiveOptionPic0();
2500 Parser.Lex();
2501 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2502 Error(Parser.getTok().getLoc(),
2503 "unexpected token in .option pic0 directive");
2504 Parser.eatToEndOfStatement();
2505 }
2506 return false;
2507 }
2508
2509 // Unknown option.
2510 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2511 Parser.eatToEndOfStatement();
2512 return false;
2513}
2514
Jack Carter0b744b32012-10-04 02:29:46 +00002515bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002516 StringRef IDVal = DirectiveID.getString();
2517
Jack Carterd0bd6422013-04-18 00:41:53 +00002518 if (IDVal == ".ent") {
2519 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002520 Parser.Lex();
2521 return false;
2522 }
2523
Jack Carter07c818d2013-01-25 01:31:34 +00002524 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002525 // 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 == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002531 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002532 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002533 return false;
2534 }
2535
Jack Carter07c818d2013-01-25 01:31:34 +00002536 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002537 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002538 }
2539
Jack Carter07c818d2013-01-25 01:31:34 +00002540 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002541 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002542 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002543 return false;
2544 }
2545
Jack Carter07c818d2013-01-25 01:31:34 +00002546 if (IDVal == ".mask") {
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 == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002553 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002554 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002555 return false;
2556 }
2557
Jack Carter07c818d2013-01-25 01:31:34 +00002558 if (IDVal == ".word") {
2559 parseDirectiveWord(4, DirectiveID.getLoc());
2560 return false;
2561 }
2562
Jack Carter0cd3c192014-01-06 23:27:31 +00002563 if (IDVal == ".option")
2564 return parseDirectiveOption();
2565
2566 if (IDVal == ".abicalls") {
2567 getTargetStreamer().emitDirectiveAbiCalls();
2568 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2569 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2570 // Clear line
2571 Parser.eatToEndOfStatement();
2572 }
2573 return false;
2574 }
2575
Rafael Espindola870c4e92012-01-11 03:56:41 +00002576 return true;
2577}
2578
Rafael Espindola870c4e92012-01-11 03:56:41 +00002579extern "C" void LLVMInitializeMipsAsmParser() {
2580 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2581 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2582 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2583 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2584}
Jack Carterb4dbc172012-09-05 23:34:03 +00002585
2586#define GET_REGISTER_MATCHER
2587#define GET_MATCHER_IMPLEMENTATION
2588#include "MipsGenAsmMatcher.inc"