blob: 0a6aee4bcee84547e6ee062ef84fadd6c9259436 [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"
Daniel Sandersa771fef2014-03-24 14:05:39 +000019#include "llvm/MC/MCInstBuilder.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000022#include "llvm/MC/MCStreamer.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000025#include "llvm/MC/MCTargetAsmParser.h"
Matheus Almeidae0d75aa2013-12-13 11:11:02 +000026#include "llvm/Support/MathExtras.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000027#include "llvm/Support/TargetRegistry.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000028
29using namespace llvm;
30
Joey Gouly0e76fa72013-09-12 10:28:05 +000031namespace llvm {
32class MCInstrInfo;
33}
34
Rafael Espindola870c4e92012-01-11 03:56:41 +000035namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000036class MipsAssemblerOptions {
37public:
Vladimir Medic4c299852013-11-06 11:27:05 +000038 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
Jack Carterb4dbc172012-09-05 23:34:03 +000039
Vladimir Medic4c299852013-11-06 11:27:05 +000040 unsigned getATRegNum() { return aTReg; }
Jack Carter0b744b32012-10-04 02:29:46 +000041 bool setATReg(unsigned Reg);
42
Vladimir Medic4c299852013-11-06 11:27:05 +000043 bool isReorder() { return reorder; }
44 void setReorder() { reorder = true; }
45 void setNoreorder() { reorder = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000046
Vladimir Medic4c299852013-11-06 11:27:05 +000047 bool isMacro() { return macro; }
48 void setMacro() { macro = true; }
49 void setNomacro() { macro = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000050
51private:
52 unsigned aTReg;
53 bool reorder;
54 bool macro;
55};
56}
57
58namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000059class MipsAsmParser : public MCTargetAsmParser {
Akira Hatanaka7605630c2012-08-17 20:16:42 +000060
Rafael Espindolaa17151a2013-10-08 13:08:17 +000061 MipsTargetStreamer &getTargetStreamer() {
Rafael Espindola4a1a3602014-01-14 01:21:46 +000062 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
Rafael Espindolaa17151a2013-10-08 13:08:17 +000063 return static_cast<MipsTargetStreamer &>(TS);
64 }
65
Jack Carterb4dbc172012-09-05 23:34:03 +000066 MCSubtargetInfo &STI;
67 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000068 MipsAssemblerOptions Options;
Vladimir Medic27c87ea2013-08-13 13:07:09 +000069 bool hasConsumedDollar;
Jack Carter0b744b32012-10-04 02:29:46 +000070
Akira Hatanaka7605630c2012-08-17 20:16:42 +000071#define GET_ASSEMBLER_HEADER
72#include "MipsGenAsmMatcher.inc"
73
Chad Rosier49963552012-10-13 00:26:04 +000074 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Vladimir Medic4c299852013-11-06 11:27:05 +000075 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000076 MCStreamer &Out, unsigned &ErrorInfo,
77 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000078
79 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
80
Chad Rosierf0e87202012-10-25 20:41:34 +000081 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
82 SMLoc NameLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +000083 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000084
85 bool ParseDirective(AsmToken DirectiveID);
86
Jack Carterb4dbc172012-09-05 23:34:03 +000087 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000088 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Vladimir Medic64828a12013-07-16 10:07:14 +000089
90 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000091 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
Jack Carter5dc8ac92013-09-25 23:50:44 +000092
93 MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +000094 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
95 int RegKind);
96
97 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000098 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000099
Vladimir Medic4c299852013-11-06 11:27:05 +0000100 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
101 int RegKind);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000102
103 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000104 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000105
Jack Carter873c7242013-01-12 01:03:14 +0000106 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000107 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000108
109 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000110 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000111
112 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000113 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000114
115 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000116 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Chad Rosier391d29972012-09-03 18:47:45 +0000117
Vladimir Medic233dd512013-06-24 10:05:34 +0000118 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000119 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000120
121 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000122 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000123
124 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000125 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic233dd512013-06-24 10:05:34 +0000126
Vladimir Medic643b3982013-07-30 10:12:14 +0000127 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000128 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000129
130 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000131 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic643b3982013-07-30 10:12:14 +0000132
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000133 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000134 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000135
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000136 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000137 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000138
139 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000140 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000141
Vladimir Medic05bcde62013-09-16 10:29:42 +0000142 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000143 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic05bcde62013-09-16 10:29:42 +0000144
Jack Carter5dc8ac92013-09-25 23:50:44 +0000145 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000146 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000147
148 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000149 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000150
151 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000152 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000153
154 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000155 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter5dc8ac92013-09-25 23:50:44 +0000156
Vladimir Medic2b953d02013-10-01 09:48:56 +0000157 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000158 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000159
160 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000161 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic2b953d02013-10-01 09:48:56 +0000162
Matheus Almeida779c5932013-11-18 12:32:49 +0000163 MipsAsmParser::OperandMatchResultTy
164 parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
165
Jack Carter3b2c96e2014-01-22 23:31:38 +0000166 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +0000167 unsigned RegKind);
Jack Carterd76b2372013-03-21 21:44:16 +0000168
Vladimir Medic4c299852013-11-06 11:27:05 +0000169 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
Jack Carterb4dbc172012-09-05 23:34:03 +0000170 StringRef Mnemonic);
171
Jack Carter873c7242013-01-12 01:03:14 +0000172 int tryParseRegister(bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000173
Vladimir Medic4c299852013-11-06 11:27:05 +0000174 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter873c7242013-01-12 01:03:14 +0000175 bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000176
Jack Carter30a59822012-10-04 04:03:53 +0000177 bool needsExpansion(MCInst &Inst);
178
179 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000180 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000181 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000182 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000183 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
185 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000187 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000188 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
189 bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000190 bool reportParseError(StringRef ErrorMsg);
191
Jack Carterb5cf5902013-04-17 00:18:04 +0000192 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000193 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000194
Vladimir Medic4c299852013-11-06 11:27:05 +0000195 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000196
197 bool isEvaluated(const MCExpr *Expr);
Jack Carter0b744b32012-10-04 02:29:46 +0000198 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000199 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000200
201 bool parseSetAtDirective();
202 bool parseSetNoAtDirective();
203 bool parseSetMacroDirective();
204 bool parseSetNoMacroDirective();
205 bool parseSetReorderDirective();
206 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000207 bool parseSetMips16Directive();
208 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000209
Jack Carterd76b2372013-03-21 21:44:16 +0000210 bool parseSetAssignment();
211
Jack Carter07c818d2013-01-25 01:31:34 +0000212 bool parseDirectiveWord(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000213 bool parseDirectiveGpWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000214
Jack Carterdc1e35d2012-09-06 20:00:02 +0000215 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000216
Jack Carterb4dbc172012-09-05 23:34:03 +0000217 bool isMips64() const {
218 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
219 }
220
Jack Cartera63b16a2012-09-07 00:23:42 +0000221 bool isFP64() const {
222 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
223 }
224
Vladimir Medic4c299852013-11-06 11:27:05 +0000225 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000226
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000227 bool isMicroMips() const {
228 return STI.getFeatureBits() & Mips::FeatureMicroMips;
229 }
230
Jack Carter873c7242013-01-12 01:03:14 +0000231 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000232
Jack Carter1ac53222013-02-20 23:11:17 +0000233 int matchCPURegisterName(StringRef Symbol);
234
Jack Carter873c7242013-01-12 01:03:14 +0000235 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000236
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000237 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000238
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000239 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000240
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000241 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000242
Jack Carter5dc8ac92013-09-25 23:50:44 +0000243 int matchMSA128RegisterName(StringRef Name);
244
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000245 int matchMSA128CtrlRegisterName(StringRef Name);
246
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000247 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000248
Jack Carterd0bd6422013-04-18 00:41:53 +0000249 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000250
Jack Carter1ac53222013-02-20 23:11:17 +0000251 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000252
253 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000254 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000255
256 // Helper function that checks if the value of a vector index is within the
257 // boundaries of accepted values for each RegisterKind
258 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
259 bool validateMSAIndex(int Val, int RegKind);
260
Vladimir Medic615b26e2014-03-04 09:54:09 +0000261 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
262 if (!(STI.getFeatureBits() & Feature)) {
263 setAvailableFeatures(ComputeAvailableFeatures(
264 STI.ToggleFeature(FeatureString)));
265 }
266 }
267
268 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
269 if (STI.getFeatureBits() & Feature) {
270 setAvailableFeatures(ComputeAvailableFeatures(
271 STI.ToggleFeature(FeatureString)));
272 }
273 }
274
Rafael Espindola870c4e92012-01-11 03:56:41 +0000275public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000276 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
277 const MCInstrInfo &MII)
278 : MCTargetAsmParser(), STI(sti), Parser(parser),
279 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000280 // Initialize the set of available features.
281 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000282
283 // Assert exactly one ABI was chosen.
284 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
285 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
286 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
287 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000288 }
289
Jack Carterb4dbc172012-09-05 23:34:03 +0000290 MCAsmParser &getParser() const { return Parser; }
291 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000292};
293}
294
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000295namespace {
296
297/// MipsOperand - Instances of this class represent a parsed Mips machine
298/// instruction.
299class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000300
Jack Carter873c7242013-01-12 01:03:14 +0000301public:
302 enum RegisterKind {
303 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000304 Kind_GPR32,
305 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000306 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000307 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000308 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000309 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000310 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000311 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000312 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000313 Kind_ACC64DSP,
314 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000315 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000316 Kind_COP2,
317 Kind_MSA128BRegs,
318 Kind_MSA128HRegs,
319 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000320 Kind_MSA128DRegs,
321 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000322 };
323
324private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000325 enum KindTy {
326 k_CondCode,
327 k_CoprocNum,
328 k_Immediate,
329 k_Memory,
330 k_PostIndexRegister,
331 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000332 k_PtrReg,
Matheus Almeida779c5932013-11-18 12:32:49 +0000333 k_Token,
334 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000335 } Kind;
336
337 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000338
Eric Christopher8996c5d2013-03-15 00:42:55 +0000339 struct Token {
340 const char *Data;
341 unsigned Length;
342 };
343
344 struct RegOp {
345 unsigned RegNum;
346 RegisterKind Kind;
347 };
348
349 struct ImmOp {
350 const MCExpr *Val;
351 };
352
353 struct MemOp {
354 unsigned Base;
355 const MCExpr *Off;
356 };
357
Jack Carterb4dbc172012-09-05 23:34:03 +0000358 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000359 struct Token Tok;
360 struct RegOp Reg;
361 struct ImmOp Imm;
362 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000363 };
364
365 SMLoc StartLoc, EndLoc;
366
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000367public:
368 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000369 assert(N == 1 && "Invalid number of operands!");
370 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000371 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000372
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000373 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
374 assert(N == 1 && "Invalid number of operands!");
375 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
376 }
377
Vladimir Medic4c299852013-11-06 11:27:05 +0000378 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000379 // Add as immediate when possible. Null MCExpr = 0.
380 if (Expr == 0)
381 Inst.addOperand(MCOperand::CreateImm(0));
382 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
383 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
384 else
385 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000386 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000387
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000388 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000389 assert(N == 1 && "Invalid number of operands!");
390 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000391 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000392 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000393
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000394 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000395 assert(N == 2 && "Invalid number of operands!");
396
397 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
398
399 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000400 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000401 }
402
403 bool isReg() const { return Kind == k_Register; }
404 bool isImm() const { return Kind == k_Immediate; }
405 bool isToken() const { return Kind == k_Token; }
406 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000407 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000408 bool isInvNum() const { return Kind == k_Immediate; }
Matheus Almeida779c5932013-11-18 12:32:49 +0000409 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000410
411 StringRef getToken() const {
412 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000413 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000414 }
415
416 unsigned getReg() const {
417 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000418 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000419 }
420
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000421 unsigned getPtrReg() const {
422 assert((Kind == k_PtrReg) && "Invalid access!");
423 return Reg.RegNum;
424 }
425
Jack Carter873c7242013-01-12 01:03:14 +0000426 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000427 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000428 Reg.Kind = RegKind;
429 }
430
Jack Carterb4dbc172012-09-05 23:34:03 +0000431 const MCExpr *getImm() const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000432 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000433 return Imm.Val;
434 }
435
Jack Carterdc1e35d2012-09-06 20:00:02 +0000436 unsigned getMemBase() const {
437 assert((Kind == k_Memory) && "Invalid access!");
438 return Mem.Base;
439 }
440
441 const MCExpr *getMemOff() const {
442 assert((Kind == k_Memory) && "Invalid access!");
443 return Mem.Off;
444 }
445
Jack Carterb4dbc172012-09-05 23:34:03 +0000446 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
447 MipsOperand *Op = new MipsOperand(k_Token);
448 Op->Tok.Data = Str.data();
449 Op->Tok.Length = Str.size();
450 Op->StartLoc = S;
451 Op->EndLoc = S;
452 return Op;
453 }
454
455 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
456 MipsOperand *Op = new MipsOperand(k_Register);
457 Op->Reg.RegNum = RegNum;
458 Op->StartLoc = S;
459 Op->EndLoc = E;
460 return Op;
461 }
462
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000463 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
464 MipsOperand *Op = new MipsOperand(k_PtrReg);
465 Op->Reg.RegNum = RegNum;
466 Op->StartLoc = S;
467 Op->EndLoc = E;
468 return Op;
469 }
470
Jack Carterb4dbc172012-09-05 23:34:03 +0000471 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
472 MipsOperand *Op = new MipsOperand(k_Immediate);
473 Op->Imm.Val = Val;
474 Op->StartLoc = S;
475 Op->EndLoc = E;
476 return Op;
477 }
478
Matheus Almeida779c5932013-11-18 12:32:49 +0000479 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
480 MipsOperand *Op = new MipsOperand(k_LSAImm);
481 Op->Imm.Val = Val;
482 Op->StartLoc = S;
483 Op->EndLoc = E;
484 return Op;
485 }
486
Jack Carter3b2c96e2014-01-22 23:31:38 +0000487 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
488 SMLoc E) {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000489 MipsOperand *Op = new MipsOperand(k_Memory);
490 Op->Mem.Base = Base;
491 Op->Mem.Off = Off;
492 Op->StartLoc = S;
493 Op->EndLoc = E;
494 return Op;
495 }
496
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000497 bool isGPR32Asm() const {
498 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000499 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000500 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000501 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
502 }
503
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000504 bool isGPR64Asm() const {
505 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000506 }
Jack Carter873c7242013-01-12 01:03:14 +0000507
508 bool isHWRegsAsm() const {
509 assert((Kind == k_Register) && "Invalid access!");
510 return Reg.Kind == Kind_HWRegs;
511 }
Jack Carter873c7242013-01-12 01:03:14 +0000512
Jack Carter873c7242013-01-12 01:03:14 +0000513 bool isCCRAsm() const {
514 assert((Kind == k_Register) && "Invalid access!");
515 return Reg.Kind == Kind_CCRRegs;
516 }
517
Vladimir Medic4c299852013-11-06 11:27:05 +0000518 bool isAFGR64Asm() const {
Vladimir Medic233dd512013-06-24 10:05:34 +0000519 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
520 }
521
522 bool isFGR64Asm() const {
523 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
524 }
525
526 bool isFGR32Asm() const {
527 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
528 }
529
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000530 bool isFGRH32Asm() const {
531 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
532 }
533
Vladimir Medic643b3982013-07-30 10:12:14 +0000534 bool isFCCRegsAsm() const {
535 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
536 }
537
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000538 bool isACC64DSPAsm() const {
539 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000540 }
541
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000542 bool isLO32DSPAsm() const {
543 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
544 }
545
546 bool isHI32DSPAsm() const {
547 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
548 }
549
Vladimir Medic4c299852013-11-06 11:27:05 +0000550 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
Vladimir Medic05bcde62013-09-16 10:29:42 +0000551
Jack Carter5dc8ac92013-09-25 23:50:44 +0000552 bool isMSA128BAsm() const {
553 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
554 }
555
556 bool isMSA128HAsm() const {
557 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
558 }
559
560 bool isMSA128WAsm() const {
561 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
562 }
563
564 bool isMSA128DAsm() const {
565 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
566 }
567
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000568 bool isMSA128CRAsm() const {
569 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
570 }
571
Jack Carterb4dbc172012-09-05 23:34:03 +0000572 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000573 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000574 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000575 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000576
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000577 virtual void print(raw_ostream &OS) const {
578 llvm_unreachable("unimplemented!");
579 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000580}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000581} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000582
Jack Carter9e65aa32013-03-22 00:05:30 +0000583namespace llvm {
584extern const MCInstrDesc MipsInsts[];
585}
586static const MCInstrDesc &getInstDesc(unsigned Opcode) {
587 return MipsInsts[Opcode];
588}
589
590bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000591 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000592 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000593
Jack Carter9e65aa32013-03-22 00:05:30 +0000594 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000595
596 if (MCID.isBranch() || MCID.isCall()) {
597 const unsigned Opcode = Inst.getOpcode();
598 MCOperand Offset;
599
600 switch (Opcode) {
601 default:
602 break;
603 case Mips::BEQ:
604 case Mips::BNE:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000605 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000606 Offset = Inst.getOperand(2);
607 if (!Offset.isImm())
608 break; // We'll deal with this situation later on when applying fixups.
609 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
610 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000611 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000612 return Error(IDLoc, "branch to misaligned address");
613 break;
614 case Mips::BGEZ:
615 case Mips::BGTZ:
616 case Mips::BLEZ:
617 case Mips::BLTZ:
618 case Mips::BGEZAL:
619 case Mips::BLTZAL:
620 case Mips::BC1F:
621 case Mips::BC1T:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000622 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000623 Offset = Inst.getOperand(1);
624 if (!Offset.isImm())
625 break; // We'll deal with this situation later on when applying fixups.
626 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
627 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000628 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000629 return Error(IDLoc, "branch to misaligned address");
630 break;
631 }
632 }
633
Jack Carterc15c1d22013-04-25 23:31:35 +0000634 if (MCID.hasDelaySlot() && Options.isReorder()) {
635 // If this instruction has a delay slot and .set reorder is active,
636 // emit a NOP after it.
637 Instructions.push_back(Inst);
638 MCInst NopInst;
639 NopInst.setOpcode(Mips::SLL);
640 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
641 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
642 NopInst.addOperand(MCOperand::CreateImm(0));
643 Instructions.push_back(NopInst);
644 return false;
645 }
646
Jack Carter9e65aa32013-03-22 00:05:30 +0000647 if (MCID.mayLoad() || MCID.mayStore()) {
648 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000649 // reference or immediate we may have to expand instructions.
650 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000651 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000652 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
653 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000654 MCOperand &Op = Inst.getOperand(i);
655 if (Op.isImm()) {
656 int MemOffset = Op.getImm();
657 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000658 // Offset can't exceed 16bit value.
659 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000660 return false;
661 }
662 } else if (Op.isExpr()) {
663 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000664 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000665 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000666 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000667 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000668 // Expand symbol.
669 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000670 return false;
671 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000672 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000673 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000674 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000675 }
676 }
677 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000678 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000679 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000680
681 if (needsExpansion(Inst))
682 expandInstruction(Inst, IDLoc, Instructions);
683 else
684 Instructions.push_back(Inst);
685
686 return false;
687}
688
Jack Carter30a59822012-10-04 04:03:53 +0000689bool MipsAsmParser::needsExpansion(MCInst &Inst) {
690
Jack Carterd0bd6422013-04-18 00:41:53 +0000691 switch (Inst.getOpcode()) {
692 case Mips::LoadImm32Reg:
693 case Mips::LoadAddr32Imm:
694 case Mips::LoadAddr32Reg:
Daniel Sandersa771fef2014-03-24 14:05:39 +0000695 case Mips::SUBi:
696 case Mips::SUBiu:
697 case Mips::DSUBi:
698 case Mips::DSUBiu:
Jack Carterd0bd6422013-04-18 00:41:53 +0000699 return true;
700 default:
701 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000702 }
703}
Jack Carter92995f12012-10-06 00:53:28 +0000704
Jack Carter30a59822012-10-04 04:03:53 +0000705void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000706 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000707 switch (Inst.getOpcode()) {
708 case Mips::LoadImm32Reg:
709 return expandLoadImm(Inst, IDLoc, Instructions);
710 case Mips::LoadAddr32Imm:
711 return expandLoadAddressImm(Inst, IDLoc, Instructions);
712 case Mips::LoadAddr32Reg:
713 return expandLoadAddressReg(Inst, IDLoc, Instructions);
Daniel Sandersa771fef2014-03-24 14:05:39 +0000714 case Mips::SUBi:
715 Instructions.push_back(MCInstBuilder(Mips::ADDi)
716 .addReg(Inst.getOperand(0).getReg())
717 .addReg(Inst.getOperand(1).getReg())
718 .addImm(-Inst.getOperand(2).getImm()));
719 return;
720 case Mips::SUBiu:
721 Instructions.push_back(MCInstBuilder(Mips::ADDiu)
722 .addReg(Inst.getOperand(0).getReg())
723 .addReg(Inst.getOperand(1).getReg())
724 .addImm(-Inst.getOperand(2).getImm()));
725 return;
726 case Mips::DSUBi:
727 Instructions.push_back(MCInstBuilder(Mips::DADDi)
728 .addReg(Inst.getOperand(0).getReg())
729 .addReg(Inst.getOperand(1).getReg())
730 .addImm(-Inst.getOperand(2).getImm()));
731 return;
732 case Mips::DSUBiu:
733 Instructions.push_back(MCInstBuilder(Mips::DADDiu)
734 .addReg(Inst.getOperand(0).getReg())
735 .addReg(Inst.getOperand(1).getReg())
736 .addImm(-Inst.getOperand(2).getImm()));
737 return;
Jack Carterd0bd6422013-04-18 00:41:53 +0000738 }
Jack Carter30a59822012-10-04 04:03:53 +0000739}
Jack Carter92995f12012-10-06 00:53:28 +0000740
Jack Carter30a59822012-10-04 04:03:53 +0000741void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000742 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000743 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000744 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000745 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000746 const MCOperand &RegOp = Inst.getOperand(0);
747 assert(RegOp.isReg() && "expected register operand kind");
748
749 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000750 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000751 if (0 <= ImmValue && ImmValue <= 65535) {
752 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000753 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000754 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000755 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000756 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000757 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000758 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000759 } else if (ImmValue < 0 && ImmValue >= -32768) {
760 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000761 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000762 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000763 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000764 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000765 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000766 Instructions.push_back(tmpInst);
767 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000768 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000769 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000770 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000771 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000772 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
773 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000774 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000775 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000776 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000777 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
778 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
779 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
780 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000781 Instructions.push_back(tmpInst);
782 }
783}
Jack Carter92995f12012-10-06 00:53:28 +0000784
Vladimir Medic4c299852013-11-06 11:27:05 +0000785void
786MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
787 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000788 MCInst tmpInst;
789 const MCOperand &ImmOp = Inst.getOperand(2);
790 assert(ImmOp.isImm() && "expected immediate operand kind");
791 const MCOperand &SrcRegOp = Inst.getOperand(1);
792 assert(SrcRegOp.isReg() && "expected register operand kind");
793 const MCOperand &DstRegOp = Inst.getOperand(0);
794 assert(DstRegOp.isReg() && "expected register operand kind");
795 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000796 if (-32768 <= ImmValue && ImmValue <= 65535) {
797 // For -32768 <= j <= 65535.
798 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000799 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000800 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
801 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
802 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
803 Instructions.push_back(tmpInst);
804 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000805 // For any other value of j that is representable as a 32-bit integer.
806 // la d,j(s) => lui d,hi16(j)
807 // ori d,d,lo16(j)
808 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000809 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000810 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
811 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
812 Instructions.push_back(tmpInst);
813 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000814 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000815 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
816 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
817 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
818 Instructions.push_back(tmpInst);
819 tmpInst.clear();
820 tmpInst.setOpcode(Mips::ADDu);
821 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
822 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
823 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
824 Instructions.push_back(tmpInst);
825 }
826}
827
Vladimir Medic4c299852013-11-06 11:27:05 +0000828void
829MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
830 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000831 MCInst tmpInst;
832 const MCOperand &ImmOp = Inst.getOperand(1);
833 assert(ImmOp.isImm() && "expected immediate operand kind");
834 const MCOperand &RegOp = Inst.getOperand(0);
835 assert(RegOp.isReg() && "expected register operand kind");
836 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000837 if (-32768 <= ImmValue && ImmValue <= 65535) {
838 // For -32768 <= j <= 65535.
839 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000840 tmpInst.setOpcode(Mips::ADDiu);
841 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000842 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000843 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
844 Instructions.push_back(tmpInst);
845 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000846 // For any other value of j that is representable as a 32-bit integer.
847 // la d,j => lui d,hi16(j)
848 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000849 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000850 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
851 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
852 Instructions.push_back(tmpInst);
853 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000854 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000855 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
856 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
857 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
858 Instructions.push_back(tmpInst);
859 }
860}
861
Jack Carter9e65aa32013-03-22 00:05:30 +0000862void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000863 SmallVectorImpl<MCInst> &Instructions,
864 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000865 const MCSymbolRefExpr *SR;
866 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000867 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000868 const MCExpr *ExprOffset;
869 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000870 unsigned AtRegNum = getReg(
871 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000872 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000873 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
874 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000875 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000876 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
877 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000878 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000879 if (isImmOpnd) {
880 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
881 ImmOffset = Inst.getOperand(2).getImm();
882 LoOffset = ImmOffset & 0x0000ffff;
883 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000884 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000885 if (LoOffset & 0x8000)
886 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000887 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000888 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000889 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000890 TempInst.setLoc(IDLoc);
891 // 1st instruction in expansion is LUi. For load instruction we can use
892 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000893 // but for stores we must use $at.
894 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000895 TempInst.setOpcode(Mips::LUi);
896 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
897 if (isImmOpnd)
898 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
899 else {
900 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000901 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000902 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
903 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
904 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000905 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000906 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000908 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000909 }
910 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000911 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000912 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000913 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000914 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000915 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000916 TempInst.setOpcode(Mips::ADDu);
917 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
918 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
919 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
920 Instructions.push_back(TempInst);
921 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +0000922 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000923 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000924 TempInst.setOpcode(Inst.getOpcode());
925 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
926 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
927 if (isImmOpnd)
928 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
929 else {
930 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000931 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
932 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
933 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000934 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000935 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000936 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000937 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000938 }
939 }
940 Instructions.push_back(TempInst);
941 TempInst.clear();
942}
943
Vladimir Medic4c299852013-11-06 11:27:05 +0000944bool MipsAsmParser::MatchAndEmitInstruction(
945 SMLoc IDLoc, unsigned &Opcode,
946 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
947 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000948 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000949 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000950 unsigned MatchResult =
951 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000952
953 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000954 default:
955 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000956 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000957 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000958 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000959 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +0000960 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +0000961 return false;
962 }
963 case Match_MissingFeature:
964 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
965 return true;
966 case Match_InvalidOperand: {
967 SMLoc ErrorLoc = IDLoc;
968 if (ErrorInfo != ~0U) {
969 if (ErrorInfo >= Operands.size())
970 return Error(IDLoc, "too few operands for instruction");
971
Vladimir Medic4c299852013-11-06 11:27:05 +0000972 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000973 if (ErrorLoc == SMLoc())
974 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000975 }
976
977 return Error(ErrorLoc, "invalid operand for instruction");
978 }
979 case Match_MnemonicFail:
980 return Error(IDLoc, "invalid instruction");
981 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000982 return true;
983}
984
Jack Carter1ac53222013-02-20 23:11:17 +0000985int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000986 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +0000987
Daniel Sanderse231ae92014-03-25 10:57:07 +0000988 if (Name == "at") {
989 // If noat is set then the at register is 0, otherwise it's defined as a
990 // specific register. Warn if the assembler is free to use it.
991 if (Options.getATRegNum() != 0)
992 Warning(getLexer().getLoc(), "Used $at without \".set noat\"");
993 return 1;
994 }
Jack Carter1ac53222013-02-20 23:11:17 +0000995
Vladimir Medic4c299852013-11-06 11:27:05 +0000996 CC = StringSwitch<unsigned>(Name)
997 .Case("zero", 0)
998 .Case("a0", 4)
999 .Case("a1", 5)
1000 .Case("a2", 6)
1001 .Case("a3", 7)
1002 .Case("v0", 2)
1003 .Case("v1", 3)
1004 .Case("s0", 16)
1005 .Case("s1", 17)
1006 .Case("s2", 18)
1007 .Case("s3", 19)
1008 .Case("s4", 20)
1009 .Case("s5", 21)
1010 .Case("s6", 22)
1011 .Case("s7", 23)
1012 .Case("k0", 26)
1013 .Case("k1", 27)
1014 .Case("sp", 29)
1015 .Case("fp", 30)
1016 .Case("gp", 28)
1017 .Case("ra", 31)
1018 .Case("t0", 8)
1019 .Case("t1", 9)
1020 .Case("t2", 10)
1021 .Case("t3", 11)
1022 .Case("t4", 12)
1023 .Case("t5", 13)
1024 .Case("t6", 14)
1025 .Case("t7", 15)
1026 .Case("t8", 24)
1027 .Case("t9", 25)
1028 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001029
Jack Carterd0bd6422013-04-18 00:41:53 +00001030 // Although SGI documentation just cuts out t0-t3 for n32/n64,
Jack Carter1ac53222013-02-20 23:11:17 +00001031 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1032 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
Jack Carterd0bd6422013-04-18 00:41:53 +00001033 if (isMips64() && 8 <= CC && CC <= 11)
Jack Carter1ac53222013-02-20 23:11:17 +00001034 CC += 4;
1035
1036 if (CC == -1 && isMips64())
1037 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001038 .Case("a4", 8)
1039 .Case("a5", 9)
1040 .Case("a6", 10)
1041 .Case("a7", 11)
1042 .Case("kt0", 26)
1043 .Case("kt1", 27)
1044 .Case("s8", 30)
1045 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001046
Daniel Sanderse231ae92014-03-25 10:57:07 +00001047 if ((CC != 0) && ((int)Options.getATRegNum() == CC))
1048 Warning(getLexer().getLoc(), Twine("Used $") + Name + " with \".set at=$"
1049 + Name + "\"");
1050
Jack Carter1ac53222013-02-20 23:11:17 +00001051 return CC;
1052}
Jack Carterd0bd6422013-04-18 00:41:53 +00001053
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001054int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001055
Jack Cartera63b16a2012-09-07 00:23:42 +00001056 if (Name[0] == 'f') {
1057 StringRef NumString = Name.substr(1);
1058 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001059 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001060 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001061 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001062 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001063 return IntVal;
1064 }
1065 return -1;
1066}
Jack Cartera63b16a2012-09-07 00:23:42 +00001067
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001068int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1069
1070 if (Name.startswith("fcc")) {
1071 StringRef NumString = Name.substr(3);
1072 unsigned IntVal;
1073 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001074 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001075 if (IntVal > 7) // There are only 8 fcc registers.
1076 return -1;
1077 return IntVal;
1078 }
1079 return -1;
1080}
1081
1082int MipsAsmParser::matchACRegisterName(StringRef Name) {
1083
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001084 if (Name.startswith("ac")) {
1085 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001086 unsigned IntVal;
1087 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001088 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001089 if (IntVal > 3) // There are only 3 acc registers.
1090 return -1;
1091 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001092 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001093 return -1;
1094}
Jack Carterd0bd6422013-04-18 00:41:53 +00001095
Jack Carter5dc8ac92013-09-25 23:50:44 +00001096int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1097 unsigned IntVal;
1098
1099 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1100 return -1;
1101
1102 if (IntVal > 31)
1103 return -1;
1104
1105 return IntVal;
1106}
1107
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001108int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1109 int CC;
1110
1111 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001112 .Case("msair", 0)
1113 .Case("msacsr", 1)
1114 .Case("msaaccess", 2)
1115 .Case("msasave", 3)
1116 .Case("msamodify", 4)
1117 .Case("msarequest", 5)
1118 .Case("msamap", 6)
1119 .Case("msaunmap", 7)
1120 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001121
1122 return CC;
1123}
1124
Vladimir Medic8cd17102013-06-20 11:21:49 +00001125int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1126
Vladimir Medic8cd17102013-06-20 11:21:49 +00001127 int CC;
1128 CC = matchCPURegisterName(Name);
1129 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001130 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1131 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001132 CC = matchFPURegisterName(Name);
Vladimir Medic4c299852013-11-06 11:27:05 +00001133 // TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001134 if (CC != -1)
1135 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1136 : Mips::FGR32RegClassID);
1137 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001138}
1139
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001140int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001141
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001142 switch (RegKind) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001143 case MipsOperand::Kind_GPR32:
1144 return Mips::GPR32RegClassID;
1145 case MipsOperand::Kind_GPR64:
1146 return Mips::GPR64RegClassID;
1147 case MipsOperand::Kind_HWRegs:
1148 return Mips::HWRegsRegClassID;
1149 case MipsOperand::Kind_FGR32Regs:
1150 return Mips::FGR32RegClassID;
1151 case MipsOperand::Kind_FGRH32Regs:
1152 return Mips::FGRH32RegClassID;
1153 case MipsOperand::Kind_FGR64Regs:
1154 return Mips::FGR64RegClassID;
1155 case MipsOperand::Kind_AFGR64Regs:
1156 return Mips::AFGR64RegClassID;
1157 case MipsOperand::Kind_CCRRegs:
1158 return Mips::CCRRegClassID;
1159 case MipsOperand::Kind_ACC64DSP:
1160 return Mips::ACC64DSPRegClassID;
1161 case MipsOperand::Kind_FCCRegs:
1162 return Mips::FCCRegClassID;
1163 case MipsOperand::Kind_MSA128BRegs:
1164 return Mips::MSA128BRegClassID;
1165 case MipsOperand::Kind_MSA128HRegs:
1166 return Mips::MSA128HRegClassID;
1167 case MipsOperand::Kind_MSA128WRegs:
1168 return Mips::MSA128WRegClassID;
1169 case MipsOperand::Kind_MSA128DRegs:
1170 return Mips::MSA128DRegClassID;
1171 case MipsOperand::Kind_MSA128CtrlRegs:
1172 return Mips::MSACtrlRegClassID;
1173 default:
1174 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001175 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001176}
Jack Carterb4dbc172012-09-05 23:34:03 +00001177
Jack Carter0b744b32012-10-04 02:29:46 +00001178bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1179 if (Reg > 31)
1180 return false;
1181
1182 aTReg = Reg;
1183 return true;
1184}
1185
Daniel Sandersd89b1362014-03-24 16:48:01 +00001186int MipsAsmParser::getATReg() {
1187 int AT = Options.getATRegNum();
1188 if (AT == 0)
1189 TokError("Pseudo instruction requires $at, which is not available");
1190 return AT;
1191}
Jack Carter0b744b32012-10-04 02:29:46 +00001192
Jack Carterd0bd6422013-04-18 00:41:53 +00001193unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001194 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001195}
1196
Jack Carter873c7242013-01-12 01:03:14 +00001197int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001198 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001199 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001200 return -1;
1201
Jack Carter873c7242013-01-12 01:03:14 +00001202 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001203}
1204
Jack Carter873c7242013-01-12 01:03:14 +00001205int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001206 const AsmToken &Tok = Parser.getTok();
1207 int RegNum = -1;
1208
1209 if (Tok.is(AsmToken::Identifier)) {
1210 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001211 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001212 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001213 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001214 is64BitReg ? Mips::GPR64RegClassID
1215 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001216 return RegNum;
1217}
1218
Jack Carterd0bd6422013-04-18 00:41:53 +00001219bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001220 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001221
1222 SMLoc S = Parser.getTok().getLoc();
1223 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001224
Jack Carter873c7242013-01-12 01:03:14 +00001225 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001226 if (RegNo == -1)
1227 return true;
1228
Vladimir Medic4c299852013-11-06 11:27:05 +00001229 Operands.push_back(
1230 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001231 Parser.Lex(); // Eat register token.
1232 return false;
1233}
1234
Vladimir Medic4c299852013-11-06 11:27:05 +00001235bool
1236MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1237 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001238 // Check if the current operand has a custom associated parser, if so, try to
1239 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001240 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1241 if (ResTy == MatchOperand_Success)
1242 return false;
1243 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1244 // there was a match, but an error occurred, in which case, just return that
1245 // the operand parsing failed.
1246 if (ResTy == MatchOperand_ParseFail)
1247 return true;
1248
1249 switch (getLexer().getKind()) {
1250 default:
1251 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1252 return true;
1253 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001254 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001255 SMLoc S = Parser.getTok().getLoc();
1256 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001257 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001258 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001259 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001260 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001261 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001262 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001263 if (getLexer().isNot(AsmToken::Dollar))
1264 return true;
1265
Jack Carterd0bd6422013-04-18 00:41:53 +00001266 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001267 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001268 return true;
1269
1270 if (!getLexer().is(AsmToken::RParen))
1271 return true;
1272
1273 S = Parser.getTok().getLoc();
1274 Operands.push_back(MipsOperand::CreateToken(")", S));
1275 Parser.Lex();
1276 }
1277 return false;
1278 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001279 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001280 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001281 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001282 return true;
1283
Jack Carter873c7242013-01-12 01:03:14 +00001284 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001285 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001286 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001287 const MCExpr *Res =
1288 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001289
1290 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1291 return false;
1292 }
1293 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001294 // For instruction aliases like "bc1f $Label" dedicated parser will
1295 // eat the '$' sign before failing. So in order to look for appropriate
1296 // label we must check first if we have already consumed '$'.
1297 if (hasConsumedDollar) {
1298 hasConsumedDollar = false;
1299 SMLoc S = Parser.getTok().getLoc();
1300 StringRef Identifier;
1301 if (Parser.parseIdentifier(Identifier))
1302 return true;
1303 SMLoc E =
1304 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1305 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1306 // Create a symbol reference.
1307 const MCExpr *Res =
1308 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1309
1310 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1311 return false;
1312 }
Jack Carterd76b2372013-03-21 21:44:16 +00001313 // Look for the existing symbol, we should check if
Matheus Almeidad534fc32014-01-30 13:40:26 +00001314 // we need to assign the proper RegisterKind.
Jack Carterd0bd6422013-04-18 00:41:53 +00001315 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1316 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001317 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001318 case AsmToken::LParen:
1319 case AsmToken::Minus:
1320 case AsmToken::Plus:
1321 case AsmToken::Integer:
1322 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001323 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001324 const MCExpr *IdVal;
1325 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001326 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001327 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001328 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001329 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1330 return false;
1331 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001332 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001333 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001334 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001335 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001336 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001337 return true;
1338
Jack Carter873c7242013-01-12 01:03:14 +00001339 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1340
Jack Carterdc1e35d2012-09-06 20:00:02 +00001341 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1342 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001343 } // case AsmToken::Percent
1344 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001345 return true;
1346}
1347
Vladimir Medic4c299852013-11-06 11:27:05 +00001348const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001349 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001350 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001351 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001352 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001353 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001354 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001355 short Val = MCE->getValue();
1356 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001357 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001358 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001359 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001360 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001361 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001362 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001363 if (LoSign)
1364 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001365 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001366 } else {
1367 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001368 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001369 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001370 }
1371
Jack Carterb5cf5902013-04-17 00:18:04 +00001372 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001373 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001374 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001375 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001376 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001377 return Res;
1378 }
1379
1380 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001381 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1382
1383 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1384 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1385 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1386 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1387 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1388 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1389 return MipsMCExpr::CreateHi(Expr, getContext());
1390 return MipsMCExpr::CreateLo(Expr, getContext());
1391 }
1392
Jack Carterd0bd6422013-04-18 00:41:53 +00001393 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1394 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001395 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1396 return Res;
1397 }
1398
1399 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001400 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1401 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1402 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001403 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001404 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001405 return Expr;
1406}
1407
1408bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1409
1410 switch (Expr->getKind()) {
1411 case MCExpr::Constant:
1412 return true;
1413 case MCExpr::SymbolRef:
1414 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1415 case MCExpr::Binary:
1416 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1417 if (!isEvaluated(BE->getLHS()))
1418 return false;
1419 return isEvaluated(BE->getRHS());
1420 }
1421 case MCExpr::Unary:
1422 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001423 case MCExpr::Target:
1424 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001425 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001426 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001427}
Jack Carterd0bd6422013-04-18 00:41:53 +00001428
Jack Carterb5cf5902013-04-17 00:18:04 +00001429bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001430 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001431 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001432 if (Tok.isNot(AsmToken::Identifier))
1433 return true;
1434
1435 std::string Str = Tok.getIdentifier().str();
1436
Jack Carterd0bd6422013-04-18 00:41:53 +00001437 Parser.Lex(); // Eat the identifier.
1438 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001439 const MCExpr *IdVal;
1440 SMLoc EndLoc;
1441
1442 if (getLexer().getKind() == AsmToken::LParen) {
1443 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001444 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001445 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001446 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001447 const AsmToken &nextTok = Parser.getTok();
1448 if (nextTok.isNot(AsmToken::Identifier))
1449 return true;
1450 Str += "(%";
1451 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001452 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001453 if (getLexer().getKind() != AsmToken::LParen)
1454 return true;
1455 } else
1456 break;
1457 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001458 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001459 return true;
1460
1461 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001462 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001463
1464 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001465 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001466
Jack Carterd0bd6422013-04-18 00:41:53 +00001467 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001468 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001469}
1470
Jack Carterb4dbc172012-09-05 23:34:03 +00001471bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1472 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001473 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001474 RegNo = tryParseRegister(isMips64());
1475 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001476 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001477}
1478
Jack Carterb5cf5902013-04-17 00:18:04 +00001479bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001480 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001481 bool Result = true;
1482
1483 while (getLexer().getKind() == AsmToken::LParen)
1484 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001485
Jack Carterd0bd6422013-04-18 00:41:53 +00001486 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001487 default:
1488 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001489 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001490 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001491 case AsmToken::Integer:
1492 case AsmToken::Minus:
1493 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001494 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001495 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001496 else
1497 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001498 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001499 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001500 break;
Jack Carter873c7242013-01-12 01:03:14 +00001501 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001502 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001503 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001504 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001505}
1506
Jack Carterb4dbc172012-09-05 23:34:03 +00001507MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001508 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001509
1510 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001511 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001512 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001513 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001514 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001515 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001516
Jack Carterb5cf5902013-04-17 00:18:04 +00001517 if (getLexer().getKind() == AsmToken::LParen) {
1518 Parser.Lex();
1519 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001520 }
1521
Jack Carterb5cf5902013-04-17 00:18:04 +00001522 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001523 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001524 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001525
Jack Carterd0bd6422013-04-18 00:41:53 +00001526 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001527 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001528 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001529 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001530 SMLoc E =
1531 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001532 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1533 return MatchOperand_Success;
1534 }
1535 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001536 SMLoc E =
1537 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001538
Jack Carterd0bd6422013-04-18 00:41:53 +00001539 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001540 Operands.push_back(MipsOperand::CreateMem(
1541 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001542 return MatchOperand_Success;
1543 }
1544 Error(Parser.getTok().getLoc(), "'(' expected");
1545 return MatchOperand_ParseFail;
1546 }
1547
Jack Carterd0bd6422013-04-18 00:41:53 +00001548 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001549 }
1550
Vladimir Medic4c299852013-11-06 11:27:05 +00001551 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1552 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001553 if (Res != MatchOperand_Success)
1554 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001555
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001556 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001557 Error(Parser.getTok().getLoc(), "')' expected");
1558 return MatchOperand_ParseFail;
1559 }
1560
Jack Carter873c7242013-01-12 01:03:14 +00001561 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1562
Jack Carterd0bd6422013-04-18 00:41:53 +00001563 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001564
1565 if (IdVal == 0)
1566 IdVal = MCConstantExpr::Create(0, getContext());
1567
Jack Carterd0bd6422013-04-18 00:41:53 +00001568 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001569 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001570 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001571 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001572 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001573 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001574 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1575 int64_t Imm;
1576 if (IdVal->EvaluateAsAbsolute(Imm))
1577 IdVal = MCConstantExpr::Create(Imm, getContext());
1578 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1579 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1580 getContext());
1581 }
1582
Jack Carterdc1e35d2012-09-06 20:00:02 +00001583 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1584 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001585 return MatchOperand_Success;
1586}
1587
Vladimir Medic4c299852013-11-06 11:27:05 +00001588bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1589 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001590 // If the first token is not '$' we have an error.
1591 if (Parser.getTok().isNot(AsmToken::Dollar))
1592 return false;
1593
1594 SMLoc S = Parser.getTok().getLoc();
1595 Parser.Lex();
1596 AsmToken::TokenKind TkKind = getLexer().getKind();
1597 int Reg;
1598
1599 if (TkKind == AsmToken::Integer) {
1600 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1601 regKindToRegClass(RegKind));
1602 if (Reg == -1)
1603 return false;
1604 } else if (TkKind == AsmToken::Identifier) {
1605 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1606 return false;
1607 Reg = getReg(regKindToRegClass(RegKind), Reg);
1608 } else {
1609 return false;
1610 }
1611
1612 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1613 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1614 Operands.push_back(Op);
1615 Parser.Lex();
1616 return true;
1617}
1618
1619MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001620MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1621 MipsOperand::RegisterKind RegKind =
1622 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001623
1624 // Parse index register.
1625 if (!parsePtrReg(Operands, RegKind))
1626 return MatchOperand_NoMatch;
1627
1628 // Parse '('.
1629 if (Parser.getTok().isNot(AsmToken::LParen))
1630 return MatchOperand_NoMatch;
1631
1632 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1633 Parser.Lex();
1634
1635 // Parse base register.
1636 if (!parsePtrReg(Operands, RegKind))
1637 return MatchOperand_NoMatch;
1638
1639 // Parse ')'.
1640 if (Parser.getTok().isNot(AsmToken::RParen))
1641 return MatchOperand_NoMatch;
1642
1643 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1644 Parser.Lex();
1645
1646 return MatchOperand_Success;
1647}
1648
Jack Carter873c7242013-01-12 01:03:14 +00001649MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001650MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001651 int RegKind) {
1652 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001653 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001654 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001655 return MatchOperand_Success;
1656 return MatchOperand_NoMatch;
1657 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001658 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001659 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001660 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001661 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001662 if (!hasConsumedDollar) {
1663 Parser.Lex(); // Eat the '$'
1664 hasConsumedDollar = true;
1665 }
1666 if (getLexer().getKind() == AsmToken::Identifier) {
1667 int RegNum = -1;
1668 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001669 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001670 switch (RegKind) {
1671 case MipsOperand::Kind_GPR32:
1672 case MipsOperand::Kind_GPR64:
1673 RegNum = matchCPURegisterName(RegName);
1674 break;
1675 case MipsOperand::Kind_AFGR64Regs:
1676 case MipsOperand::Kind_FGR64Regs:
1677 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001678 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001679 RegNum = matchFPURegisterName(RegName);
1680 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1681 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001682 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1683 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001684 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001685 break;
1686 case MipsOperand::Kind_FCCRegs:
1687 RegNum = matchFCCRegisterName(RegName);
1688 break;
1689 case MipsOperand::Kind_ACC64DSP:
1690 RegNum = matchACRegisterName(RegName);
1691 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001692 default:
1693 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001694 }
1695 // No match found, return _NoMatch to give a chance to other round.
1696 if (RegNum < 0)
1697 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001698
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001699 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1700 if (RegVal == -1)
1701 return MatchOperand_NoMatch;
1702
Vladimir Medic4c299852013-11-06 11:27:05 +00001703 MipsOperand *Op =
1704 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001705 Op->setRegKind(Kind);
1706 Operands.push_back(Op);
1707 hasConsumedDollar = false;
1708 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001709 return MatchOperand_Success;
1710 } else if (getLexer().getKind() == AsmToken::Integer) {
1711 unsigned RegNum = Parser.getTok().getIntVal();
1712 if (Kind == MipsOperand::Kind_HWRegs) {
1713 if (RegNum != 29)
1714 return MatchOperand_NoMatch;
1715 // Only hwreg 29 is supported, found at index 0.
1716 RegNum = 0;
1717 }
1718 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1719 if (Reg == -1)
1720 return MatchOperand_NoMatch;
1721 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1722 Op->setRegKind(Kind);
1723 Operands.push_back(Op);
1724 hasConsumedDollar = false;
1725 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001726 if ((RegKind == MipsOperand::Kind_GPR32) &&
1727 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001728 // Check if it is indexed addressing operand.
1729 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1730 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001731 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001732 return MatchOperand_NoMatch;
1733 if (getLexer().isNot(AsmToken::RParen))
1734 return MatchOperand_NoMatch;
1735 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1736 Parser.Lex();
1737 }
Jack Carter873c7242013-01-12 01:03:14 +00001738 return MatchOperand_Success;
1739 }
1740 return MatchOperand_NoMatch;
1741}
Vladimir Medic64828a12013-07-16 10:07:14 +00001742
Matheus Almeidab74293d2013-10-14 11:49:30 +00001743bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1744 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1745
1746 if (Val < 0)
1747 return false;
1748
1749 switch (Kind) {
1750 default:
1751 return false;
1752 case MipsOperand::Kind_MSA128BRegs:
1753 return Val < 16;
1754 case MipsOperand::Kind_MSA128HRegs:
1755 return Val < 8;
1756 case MipsOperand::Kind_MSA128WRegs:
1757 return Val < 4;
1758 case MipsOperand::Kind_MSA128DRegs:
1759 return Val < 2;
1760 }
1761}
1762
Vladimir Medic8cd17102013-06-20 11:21:49 +00001763MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001764MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001765 int RegKind) {
1766 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1767 SMLoc S = Parser.getTok().getLoc();
1768 std::string RegName;
1769
1770 if (Parser.getTok().isNot(AsmToken::Dollar))
1771 return MatchOperand_NoMatch;
1772
1773 switch (RegKind) {
1774 default:
1775 return MatchOperand_ParseFail;
1776 case MipsOperand::Kind_MSA128BRegs:
1777 case MipsOperand::Kind_MSA128HRegs:
1778 case MipsOperand::Kind_MSA128WRegs:
1779 case MipsOperand::Kind_MSA128DRegs:
1780 break;
1781 }
1782
1783 Parser.Lex(); // Eat the '$'.
1784 if (getLexer().getKind() == AsmToken::Identifier)
1785 RegName = Parser.getTok().getString().lower();
1786 else
1787 return MatchOperand_ParseFail;
1788
1789 int RegNum = matchMSA128RegisterName(RegName);
1790
1791 if (RegNum < 0 || RegNum > 31)
1792 return MatchOperand_ParseFail;
1793
1794 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1795 if (RegVal == -1)
1796 return MatchOperand_ParseFail;
1797
Vladimir Medic4c299852013-11-06 11:27:05 +00001798 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001799 Op->setRegKind(Kind);
1800 Operands.push_back(Op);
1801
1802 Parser.Lex(); // Eat the register identifier.
1803
Matheus Almeidab74293d2013-10-14 11:49:30 +00001804 // MSA registers may be suffixed with an index in the form of:
1805 // 1) Immediate expression.
1806 // 2) General Purpose Register.
1807 // Examples:
1808 // 1) copy_s.b $29,$w0[0]
1809 // 2) sld.b $w0,$w1[$1]
1810
1811 if (Parser.getTok().isNot(AsmToken::LBrac))
1812 return MatchOperand_Success;
1813
1814 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1815
1816 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1817 Parser.Lex(); // Parse the '[' token.
1818
1819 if (Parser.getTok().is(AsmToken::Dollar)) {
1820 // This must be a GPR.
1821 MipsOperand *RegOp;
1822 SMLoc VIdx = Parser.getTok().getLoc();
1823 Parser.Lex(); // Parse the '$' token.
1824
1825 // GPR have aliases and we must account for that. Example: $30 == $fp
1826 if (getLexer().getKind() == AsmToken::Integer) {
1827 unsigned RegNum = Parser.getTok().getIntVal();
1828 int Reg = matchRegisterByNumber(
1829 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1830 if (Reg == -1) {
1831 Error(VIdx, "invalid general purpose register");
1832 return MatchOperand_ParseFail;
1833 }
1834
1835 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1836 } else if (getLexer().getKind() == AsmToken::Identifier) {
1837 int RegNum = -1;
1838 std::string RegName = Parser.getTok().getString().lower();
1839
1840 RegNum = matchCPURegisterName(RegName);
1841 if (RegNum == -1) {
1842 Error(VIdx, "general purpose register expected");
1843 return MatchOperand_ParseFail;
1844 }
1845 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1846 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1847 } else
1848 return MatchOperand_ParseFail;
1849
1850 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1851 Operands.push_back(RegOp);
1852 Parser.Lex(); // Eat the register identifier.
1853
1854 if (Parser.getTok().isNot(AsmToken::RBrac))
1855 return MatchOperand_ParseFail;
1856
1857 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1858 Parser.Lex(); // Parse the ']' token.
1859
1860 return MatchOperand_Success;
1861 }
1862
1863 // The index must be a constant expression then.
1864 SMLoc VIdx = Parser.getTok().getLoc();
1865 const MCExpr *ImmVal;
1866
1867 if (getParser().parseExpression(ImmVal))
1868 return MatchOperand_ParseFail;
1869
1870 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1871 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1872 Error(VIdx, "invalid immediate value");
1873 return MatchOperand_ParseFail;
1874 }
1875
1876 SMLoc E = Parser.getTok().getEndLoc();
1877
1878 if (Parser.getTok().isNot(AsmToken::RBrac))
1879 return MatchOperand_ParseFail;
1880
Vladimir Medic4c299852013-11-06 11:27:05 +00001881 bool insve =
1882 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1883 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001884
1885 // The second vector index of insve instructions is always 0.
1886 if (insve && Operands.size() > 6) {
1887 if (expr->getValue() != 0) {
1888 Error(VIdx, "immediate value must be 0");
1889 return MatchOperand_ParseFail;
1890 }
1891 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1892 } else
1893 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1894
1895 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1896
1897 Parser.Lex(); // Parse the ']' token.
1898
Jack Carter5dc8ac92013-09-25 23:50:44 +00001899 return MatchOperand_Success;
1900}
1901
1902MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001903MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1904 int RegKind) {
1905 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1906
1907 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1908 return MatchOperand_NoMatch;
1909
1910 if (Parser.getTok().isNot(AsmToken::Dollar))
1911 return MatchOperand_ParseFail;
1912
1913 SMLoc S = Parser.getTok().getLoc();
1914
1915 Parser.Lex(); // Eat the '$' symbol.
1916
1917 int RegNum = -1;
1918 if (getLexer().getKind() == AsmToken::Identifier)
1919 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1920 else if (getLexer().getKind() == AsmToken::Integer)
1921 RegNum = Parser.getTok().getIntVal();
1922 else
1923 return MatchOperand_ParseFail;
1924
1925 if (RegNum < 0 || RegNum > 7)
1926 return MatchOperand_ParseFail;
1927
1928 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1929 if (RegVal == -1)
1930 return MatchOperand_ParseFail;
1931
Vladimir Medic4c299852013-11-06 11:27:05 +00001932 MipsOperand *RegOp =
1933 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001934 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1935 Operands.push_back(RegOp);
1936 Parser.Lex(); // Eat the register identifier.
1937
1938 return MatchOperand_Success;
1939}
1940
1941MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001942MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001943
1944 if (!isMips64())
1945 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001946 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001947}
1948
1949MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001950MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1951 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001952}
Jack Carter873c7242013-01-12 01:03:14 +00001953
Vladimir Medic4c299852013-11-06 11:27:05 +00001954MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1955 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001956
1957 if (isFP64())
1958 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001959 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001960}
1961
1962MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001963MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001964 if (!isFP64())
1965 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001966 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001967}
1968
1969MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001970MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1971 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1972}
1973
1974MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1975 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1976 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001977}
1978
Vladimir Medic643b3982013-07-30 10:12:14 +00001979MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001980MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1981 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001982}
1983
1984MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001985MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1986 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001987}
1988
Akira Hatanaka34a32c02013-08-06 22:20:40 +00001989MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001990MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00001991 // If the first token is not '$' we have an error.
1992 if (Parser.getTok().isNot(AsmToken::Dollar))
1993 return MatchOperand_NoMatch;
1994
1995 SMLoc S = Parser.getTok().getLoc();
1996 Parser.Lex(); // Eat the '$'
1997
1998 const AsmToken &Tok = Parser.getTok(); // Get next token.
1999
2000 if (Tok.isNot(AsmToken::Identifier))
2001 return MatchOperand_NoMatch;
2002
2003 if (!Tok.getIdentifier().startswith("ac"))
2004 return MatchOperand_NoMatch;
2005
2006 StringRef NumString = Tok.getIdentifier().substr(2);
2007
2008 unsigned IntVal;
2009 if (NumString.getAsInteger(10, IntVal))
2010 return MatchOperand_NoMatch;
2011
2012 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
2013
2014 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2015 Op->setRegKind(MipsOperand::Kind_LO32DSP);
2016 Operands.push_back(Op);
2017
2018 Parser.Lex(); // Eat the register number.
2019 return MatchOperand_Success;
2020}
2021
2022MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002023MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00002024 // If the first token is not '$' we have an error.
2025 if (Parser.getTok().isNot(AsmToken::Dollar))
2026 return MatchOperand_NoMatch;
2027
2028 SMLoc S = Parser.getTok().getLoc();
2029 Parser.Lex(); // Eat the '$'
2030
2031 const AsmToken &Tok = Parser.getTok(); // Get next token.
2032
2033 if (Tok.isNot(AsmToken::Identifier))
2034 return MatchOperand_NoMatch;
2035
2036 if (!Tok.getIdentifier().startswith("ac"))
2037 return MatchOperand_NoMatch;
2038
2039 StringRef NumString = Tok.getIdentifier().substr(2);
2040
2041 unsigned IntVal;
2042 if (NumString.getAsInteger(10, IntVal))
2043 return MatchOperand_NoMatch;
2044
2045 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
2046
2047 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2048 Op->setRegKind(MipsOperand::Kind_HI32DSP);
2049 Operands.push_back(Op);
2050
2051 Parser.Lex(); // Eat the register number.
2052 return MatchOperand_Success;
2053}
2054
Vladimir Medic05bcde62013-09-16 10:29:42 +00002055MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002056MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00002057 // If the first token is not '$' we have an error.
2058 if (Parser.getTok().isNot(AsmToken::Dollar))
2059 return MatchOperand_NoMatch;
2060
2061 SMLoc S = Parser.getTok().getLoc();
2062 Parser.Lex(); // Eat the '$'
2063
2064 const AsmToken &Tok = Parser.getTok(); // Get next token.
2065
2066 if (Tok.isNot(AsmToken::Integer))
2067 return MatchOperand_NoMatch;
2068
2069 unsigned IntVal = Tok.getIntVal();
2070
2071 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2072
2073 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2074 Op->setRegKind(MipsOperand::Kind_COP2);
2075 Operands.push_back(Op);
2076
2077 Parser.Lex(); // Eat the register number.
2078 return MatchOperand_Success;
2079}
2080
Vladimir Medic4c299852013-11-06 11:27:05 +00002081MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2082 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2083 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002084}
2085
Vladimir Medic4c299852013-11-06 11:27:05 +00002086MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2087 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2088 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002089}
2090
Vladimir Medic4c299852013-11-06 11:27:05 +00002091MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2092 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2093 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002094}
2095
Vladimir Medic4c299852013-11-06 11:27:05 +00002096MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2097 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2098 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002099}
2100
Vladimir Medic4c299852013-11-06 11:27:05 +00002101MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2102 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2103 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002104}
2105
Jack Carterd0bd6422013-04-18 00:41:53 +00002106bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002107 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002108
2109 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2110 if (Sym) {
2111 SMLoc S = Parser.getTok().getLoc();
2112 const MCExpr *Expr;
2113 if (Sym->isVariable())
2114 Expr = Sym->getVariableValue();
2115 else
2116 return false;
2117 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002118 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2119 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002120 const StringRef DefSymbol = Ref->getSymbol().getName();
2121 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002122 int RegNum = -1;
2123 APInt IntVal(32, -1);
2124 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2125 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002126 isMips64() ? Mips::GPR64RegClassID
2127 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002128 else {
2129 // Lookup for the register with the corresponding name.
2130 switch (Kind) {
2131 case MipsOperand::Kind_AFGR64Regs:
2132 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002133 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002134 break;
2135 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002136 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002137 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002138 case MipsOperand::Kind_GPR64:
2139 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002140 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002141 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002142 break;
2143 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002144 if (RegNum > -1)
2145 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002146 }
Jack Carterd76b2372013-03-21 21:44:16 +00002147 if (RegNum > -1) {
2148 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002149 MipsOperand *op =
2150 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002151 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002152 Operands.push_back(op);
2153 return true;
2154 }
2155 }
2156 } else if (Expr->getKind() == MCExpr::Constant) {
2157 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002158 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2159 MipsOperand *op =
2160 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002161 Operands.push_back(op);
2162 return true;
2163 }
2164 }
2165 return false;
2166}
Jack Carterd0bd6422013-04-18 00:41:53 +00002167
Jack Carter873c7242013-01-12 01:03:14 +00002168MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002169MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2170 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002171}
2172
2173MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002174MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2175 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002176}
2177
Vladimir Medic2b953d02013-10-01 09:48:56 +00002178MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002179MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002180 const MCExpr *IdVal;
2181 // If the first token is '$' we may have register operand.
2182 if (Parser.getTok().is(AsmToken::Dollar))
2183 return MatchOperand_NoMatch;
2184 SMLoc S = Parser.getTok().getLoc();
2185 if (getParser().parseExpression(IdVal))
2186 return MatchOperand_ParseFail;
2187 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002188 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002189 int64_t Val = MCE->getValue();
2190 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2191 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002192 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002193 return MatchOperand_Success;
2194}
2195
Matheus Almeida779c5932013-11-18 12:32:49 +00002196MipsAsmParser::OperandMatchResultTy
2197MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2198 switch (getLexer().getKind()) {
2199 default:
2200 return MatchOperand_NoMatch;
2201 case AsmToken::LParen:
2202 case AsmToken::Plus:
2203 case AsmToken::Minus:
2204 case AsmToken::Integer:
2205 break;
2206 }
2207
2208 const MCExpr *Expr;
2209 SMLoc S = Parser.getTok().getLoc();
2210
2211 if (getParser().parseExpression(Expr))
2212 return MatchOperand_ParseFail;
2213
2214 int64_t Val;
2215 if (!Expr->EvaluateAsAbsolute(Val)) {
2216 Error(S, "expected immediate value");
2217 return MatchOperand_ParseFail;
2218 }
2219
2220 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2221 // and because the CPU always adds one to the immediate field, the allowed
2222 // range becomes 1..4. We'll only check the range here and will deal
2223 // with the addition/subtraction when actually decoding/encoding
2224 // the instruction.
2225 if (Val < 1 || Val > 4) {
2226 Error(S, "immediate not in range (1..4)");
2227 return MatchOperand_ParseFail;
2228 }
2229
Jack Carter3b2c96e2014-01-22 23:31:38 +00002230 Operands.push_back(
2231 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002232 return MatchOperand_Success;
2233}
2234
Jack Carterdc1e35d2012-09-06 20:00:02 +00002235MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2236
Vladimir Medic4c299852013-11-06 11:27:05 +00002237 MCSymbolRefExpr::VariantKind VK =
2238 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2239 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2240 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2241 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2242 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2243 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2244 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2245 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2246 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2247 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2248 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2249 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2250 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2251 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2252 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2253 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2254 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2255 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2256 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002257
2258 return VK;
2259}
Jack Cartera63b16a2012-09-07 00:23:42 +00002260
Vladimir Medic4c299852013-11-06 11:27:05 +00002261bool MipsAsmParser::ParseInstruction(
2262 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2263 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002264 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002265 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002266 Parser.eatToEndOfStatement();
2267 return Error(NameLoc, "Unknown instruction");
2268 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002269 // First operand in MCInst is instruction mnemonic.
2270 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002271
2272 // Read the remaining operands.
2273 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2274 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002275 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002276 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002277 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002278 return Error(Loc, "unexpected token in argument list");
2279 }
2280
Jack Carterd0bd6422013-04-18 00:41:53 +00002281 while (getLexer().is(AsmToken::Comma)) {
2282 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002283 // Parse and remember the operand.
2284 if (ParseOperand(Operands, Name)) {
2285 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002286 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002287 return Error(Loc, "unexpected token in argument list");
2288 }
2289 }
2290 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002291 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2292 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002293 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002294 return Error(Loc, "unexpected token in argument list");
2295 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002296 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002297 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002298}
2299
Jack Carter0b744b32012-10-04 02:29:46 +00002300bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002301 SMLoc Loc = getLexer().getLoc();
2302 Parser.eatToEndOfStatement();
2303 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002304}
2305
2306bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002307 // Line should look like: ".set noat".
2308 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002309 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002310 // eat noat
2311 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002312 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002313 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2314 reportParseError("unexpected token in statement");
2315 return false;
2316 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002317 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002318 return false;
2319}
Jack Carterd0bd6422013-04-18 00:41:53 +00002320
Jack Carter0b744b32012-10-04 02:29:46 +00002321bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002322 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002323 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002324 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002325 getParser().Lex();
2326 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002327 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002328 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002329 return false;
2330 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002331 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002332 if (getLexer().isNot(AsmToken::Dollar)) {
2333 reportParseError("unexpected token in statement");
2334 return false;
2335 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002336 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002337 const AsmToken &Reg = Parser.getTok();
2338 if (Reg.is(AsmToken::Identifier)) {
2339 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2340 } else if (Reg.is(AsmToken::Integer)) {
2341 AtRegNo = Reg.getIntVal();
2342 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002343 reportParseError("unexpected token in statement");
2344 return false;
2345 }
Jack Carter1ac53222013-02-20 23:11:17 +00002346
Jack Carterd0bd6422013-04-18 00:41:53 +00002347 if (AtRegNo < 1 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002348 reportParseError("unexpected token in statement");
2349 return false;
2350 }
2351
2352 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002353 reportParseError("unexpected token in statement");
2354 return false;
2355 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002356 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002357
2358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2359 reportParseError("unexpected token in statement");
2360 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002361 }
2362 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002363 return false;
2364 } else {
2365 reportParseError("unexpected token in statement");
2366 return false;
2367 }
2368}
2369
2370bool MipsAsmParser::parseSetReorderDirective() {
2371 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002372 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002373 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2374 reportParseError("unexpected token in statement");
2375 return false;
2376 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002377 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002378 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002379 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002380 return false;
2381}
2382
2383bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002384 Parser.Lex();
2385 // If this is not the end of the statement, report an error.
2386 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2387 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002388 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002389 }
2390 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002391 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002392 Parser.Lex(); // Consume the EndOfStatement.
2393 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002394}
2395
2396bool MipsAsmParser::parseSetMacroDirective() {
2397 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002398 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2400 reportParseError("unexpected token in statement");
2401 return false;
2402 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002403 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002404 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002405 return false;
2406}
2407
2408bool MipsAsmParser::parseSetNoMacroDirective() {
2409 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002410 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002411 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2412 reportParseError("`noreorder' must be set before `nomacro'");
2413 return false;
2414 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002415 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002416 reportParseError("`noreorder' must be set before `nomacro'");
2417 return false;
2418 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002419 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002420 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002421 return false;
2422}
Jack Carterd76b2372013-03-21 21:44:16 +00002423
Jack Carter39536722014-01-22 23:08:42 +00002424bool MipsAsmParser::parseSetMips16Directive() {
2425 Parser.Lex();
2426 // If this is not the end of the statement, report an error.
2427 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2428 reportParseError("unexpected token in statement");
2429 return false;
2430 }
Rafael Espindolae7583752014-01-24 16:13:20 +00002431 getTargetStreamer().emitDirectiveSetMips16();
Jack Carter39536722014-01-22 23:08:42 +00002432 Parser.Lex(); // Consume the EndOfStatement.
2433 return false;
2434}
2435
2436bool MipsAsmParser::parseSetNoMips16Directive() {
2437 Parser.Lex();
2438 // If this is not the end of the statement, report an error.
2439 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2440 reportParseError("unexpected token in statement");
2441 return false;
2442 }
2443 // For now do nothing.
2444 Parser.Lex(); // Consume the EndOfStatement.
2445 return false;
2446}
2447
Jack Carterd76b2372013-03-21 21:44:16 +00002448bool MipsAsmParser::parseSetAssignment() {
2449 StringRef Name;
2450 const MCExpr *Value;
2451
2452 if (Parser.parseIdentifier(Name))
2453 reportParseError("expected identifier after .set");
2454
2455 if (getLexer().isNot(AsmToken::Comma))
2456 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002457 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002458
Jack Carter3b2c96e2014-01-22 23:31:38 +00002459 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002460 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002461
Jack Carterd0bd6422013-04-18 00:41:53 +00002462 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002463 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002464 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002465 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002466 Sym = getContext().GetOrCreateSymbol(Name);
2467 Sym->setVariableValue(Value);
2468
2469 return false;
2470}
Jack Carterd0bd6422013-04-18 00:41:53 +00002471
Jack Carter0b744b32012-10-04 02:29:46 +00002472bool MipsAsmParser::parseDirectiveSet() {
2473
Jack Carterd0bd6422013-04-18 00:41:53 +00002474 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002475 const AsmToken &Tok = Parser.getTok();
2476
2477 if (Tok.getString() == "noat") {
2478 return parseSetNoAtDirective();
2479 } else if (Tok.getString() == "at") {
2480 return parseSetAtDirective();
2481 } else if (Tok.getString() == "reorder") {
2482 return parseSetReorderDirective();
2483 } else if (Tok.getString() == "noreorder") {
2484 return parseSetNoReorderDirective();
2485 } else if (Tok.getString() == "macro") {
2486 return parseSetMacroDirective();
2487 } else if (Tok.getString() == "nomacro") {
2488 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002489 } else if (Tok.getString() == "mips16") {
2490 return parseSetMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002491 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002492 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002493 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002494 getTargetStreamer().emitDirectiveSetNoMicroMips();
2495 Parser.eatToEndOfStatement();
2496 return false;
2497 } else if (Tok.getString() == "micromips") {
2498 getTargetStreamer().emitDirectiveSetMicroMips();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002499 Parser.eatToEndOfStatement();
Jack Carter0b744b32012-10-04 02:29:46 +00002500 return false;
Vladimir Medic615b26e2014-03-04 09:54:09 +00002501 } else if (Tok.getString() == "mips32r2") {
2502 Parser.Lex(); // Eat token.
2503 if (getLexer().isNot(AsmToken::EndOfStatement))
2504 return reportParseError("unexpected token in .set directive");
2505 setFeatureBits(Mips::FeatureMips32r2,"mips32r2");
2506 getTargetStreamer().emitDirectiveSetMips32R2();
2507 return false;
Vladimir Medic27c398e2014-03-05 11:05:09 +00002508 } else if (Tok.getString() == "dsp") {
2509 Parser.Lex(); // Eat token.
2510 if (getLexer().isNot(AsmToken::EndOfStatement))
2511 return reportParseError("unexpected token in .set directive");
2512 setFeatureBits(Mips::FeatureDSP, "dsp");
2513 getTargetStreamer().emitDirectiveSetDsp();
2514 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00002515 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002516 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002517 parseSetAssignment();
2518 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002519 }
Jack Carter07c818d2013-01-25 01:31:34 +00002520
Jack Carter0b744b32012-10-04 02:29:46 +00002521 return true;
2522}
2523
Jack Carter07c818d2013-01-25 01:31:34 +00002524/// parseDirectiveWord
2525/// ::= .word [ expression (, expression)* ]
2526bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2527 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2528 for (;;) {
2529 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002530 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002531 return true;
2532
2533 getParser().getStreamer().EmitValue(Value, Size);
2534
2535 if (getLexer().is(AsmToken::EndOfStatement))
2536 break;
2537
2538 // FIXME: Improve diagnostic.
2539 if (getLexer().isNot(AsmToken::Comma))
2540 return Error(L, "unexpected token in directive");
2541 Parser.Lex();
2542 }
2543 }
2544
2545 Parser.Lex();
2546 return false;
2547}
2548
Vladimir Medic4c299852013-11-06 11:27:05 +00002549/// parseDirectiveGpWord
2550/// ::= .gpword local_sym
2551bool MipsAsmParser::parseDirectiveGpWord() {
2552 const MCExpr *Value;
2553 // EmitGPRel32Value requires an expression, so we are using base class
2554 // method to evaluate the expression.
2555 if (getParser().parseExpression(Value))
2556 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002557 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002558
Vladimir Medice10c1122013-11-13 13:18:04 +00002559 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002560 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002561 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002562 return false;
2563}
2564
Jack Carter0cd3c192014-01-06 23:27:31 +00002565bool MipsAsmParser::parseDirectiveOption() {
2566 // Get the option token.
2567 AsmToken Tok = Parser.getTok();
2568 // At the moment only identifiers are supported.
2569 if (Tok.isNot(AsmToken::Identifier)) {
2570 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2571 Parser.eatToEndOfStatement();
2572 return false;
2573 }
2574
2575 StringRef Option = Tok.getIdentifier();
2576
2577 if (Option == "pic0") {
2578 getTargetStreamer().emitDirectiveOptionPic0();
2579 Parser.Lex();
2580 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2581 Error(Parser.getTok().getLoc(),
2582 "unexpected token in .option pic0 directive");
2583 Parser.eatToEndOfStatement();
2584 }
2585 return false;
2586 }
2587
2588 // Unknown option.
2589 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2590 Parser.eatToEndOfStatement();
2591 return false;
2592}
2593
Jack Carter0b744b32012-10-04 02:29:46 +00002594bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002595 StringRef IDVal = DirectiveID.getString();
2596
Jack Carterd0bd6422013-04-18 00:41:53 +00002597 if (IDVal == ".ent") {
2598 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002599 Parser.Lex();
2600 return false;
2601 }
2602
Jack Carter07c818d2013-01-25 01:31:34 +00002603 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002604 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002605 Parser.Lex();
2606 return false;
2607 }
2608
Jack Carter07c818d2013-01-25 01:31:34 +00002609 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002610 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002611 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002612 return false;
2613 }
2614
Jack Carter07c818d2013-01-25 01:31:34 +00002615 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002616 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002617 }
2618
Jack Carter07c818d2013-01-25 01:31:34 +00002619 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002620 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002621 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002622 return false;
2623 }
2624
Jack Carter07c818d2013-01-25 01:31:34 +00002625 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002626 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002627 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002628 return false;
2629 }
2630
Jack Carter07c818d2013-01-25 01:31:34 +00002631 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002632 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002633 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002634 return false;
2635 }
2636
Jack Carter07c818d2013-01-25 01:31:34 +00002637 if (IDVal == ".word") {
2638 parseDirectiveWord(4, DirectiveID.getLoc());
2639 return false;
2640 }
2641
Jack Carter0cd3c192014-01-06 23:27:31 +00002642 if (IDVal == ".option")
2643 return parseDirectiveOption();
2644
2645 if (IDVal == ".abicalls") {
2646 getTargetStreamer().emitDirectiveAbiCalls();
2647 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2648 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2649 // Clear line
2650 Parser.eatToEndOfStatement();
2651 }
2652 return false;
2653 }
2654
Rafael Espindola870c4e92012-01-11 03:56:41 +00002655 return true;
2656}
2657
Rafael Espindola870c4e92012-01-11 03:56:41 +00002658extern "C" void LLVMInitializeMipsAsmParser() {
2659 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2660 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2661 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2662 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2663}
Jack Carterb4dbc172012-09-05 23:34:03 +00002664
2665#define GET_REGISTER_MATCHER
2666#define GET_MATCHER_IMPLEMENTATION
2667#include "MipsGenAsmMatcher.inc"