blob: 36c4e2aa9edaf8248c34a758767699e166b1e414 [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);
Matheus Almeidafe1e39d2014-03-26 14:26:27 +0000198 bool parseSetFeature(uint64_t Feature);
Jack Carter0b744b32012-10-04 02:29:46 +0000199 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000200 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000201
202 bool parseSetAtDirective();
203 bool parseSetNoAtDirective();
204 bool parseSetMacroDirective();
205 bool parseSetNoMacroDirective();
206 bool parseSetReorderDirective();
207 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000208 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000209
Jack Carterd76b2372013-03-21 21:44:16 +0000210 bool parseSetAssignment();
211
Matheus Almeida3e2a7022014-03-26 15:24:36 +0000212 bool parseDataDirective(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
Daniel Sandersa4b0c742014-03-26 11:39:07 +0000225 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
Vladimir Medic4c299852013-11-06 11:27:05 +0000226 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000227
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000228 bool isMicroMips() const {
229 return STI.getFeatureBits() & Mips::FeatureMicroMips;
230 }
231
Jack Carter873c7242013-01-12 01:03:14 +0000232 int matchRegisterName(StringRef Symbol, bool is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +0000233
Jack Carter1ac53222013-02-20 23:11:17 +0000234 int matchCPURegisterName(StringRef Symbol);
235
Jack Carter873c7242013-01-12 01:03:14 +0000236 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000237
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000238 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000239
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000240 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000241
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000242 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000243
Jack Carter5dc8ac92013-09-25 23:50:44 +0000244 int matchMSA128RegisterName(StringRef Name);
245
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000246 int matchMSA128CtrlRegisterName(StringRef Name);
247
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000248 int regKindToRegClass(int RegKind);
Jack Cartera63b16a2012-09-07 00:23:42 +0000249
Jack Carterd0bd6422013-04-18 00:41:53 +0000250 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000251
Jack Carter1ac53222013-02-20 23:11:17 +0000252 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000253
Daniel Sandersb1d7e532014-03-25 11:16:03 +0000254 // Warn if RegNo is the current assembler temporary.
255 void warnIfAssemblerTemporary(int RegNo);
256
Jack Carter9e65aa32013-03-22 00:05:30 +0000257 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000258 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000259
260 // Helper function that checks if the value of a vector index is within the
261 // boundaries of accepted values for each RegisterKind
262 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
263 bool validateMSAIndex(int Val, int RegKind);
264
Vladimir Medic615b26e2014-03-04 09:54:09 +0000265 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
266 if (!(STI.getFeatureBits() & Feature)) {
267 setAvailableFeatures(ComputeAvailableFeatures(
268 STI.ToggleFeature(FeatureString)));
269 }
270 }
271
272 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
273 if (STI.getFeatureBits() & Feature) {
274 setAvailableFeatures(ComputeAvailableFeatures(
275 STI.ToggleFeature(FeatureString)));
276 }
277 }
278
Rafael Espindola870c4e92012-01-11 03:56:41 +0000279public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000280 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
281 const MCInstrInfo &MII)
282 : MCTargetAsmParser(), STI(sti), Parser(parser),
283 hasConsumedDollar(false) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000284 // Initialize the set of available features.
285 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000286
287 // Assert exactly one ABI was chosen.
288 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
289 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
290 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
291 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000292 }
293
Jack Carterb4dbc172012-09-05 23:34:03 +0000294 MCAsmParser &getParser() const { return Parser; }
295 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000296};
297}
298
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000299namespace {
300
301/// MipsOperand - Instances of this class represent a parsed Mips machine
302/// instruction.
303class MipsOperand : public MCParsedAsmOperand {
Jack Carterb4dbc172012-09-05 23:34:03 +0000304
Jack Carter873c7242013-01-12 01:03:14 +0000305public:
306 enum RegisterKind {
307 Kind_None,
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000308 Kind_GPR32,
309 Kind_GPR64,
Jack Carter873c7242013-01-12 01:03:14 +0000310 Kind_HWRegs,
Jack Carter873c7242013-01-12 01:03:14 +0000311 Kind_FGR32Regs,
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000312 Kind_FGRH32Regs,
Jack Carter873c7242013-01-12 01:03:14 +0000313 Kind_FGR64Regs,
Jack Carter1ac53222013-02-20 23:11:17 +0000314 Kind_AFGR64Regs,
Vladimir Medic643b3982013-07-30 10:12:14 +0000315 Kind_CCRRegs,
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000316 Kind_FCCRegs,
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000317 Kind_ACC64DSP,
318 Kind_LO32DSP,
Vladimir Medic05bcde62013-09-16 10:29:42 +0000319 Kind_HI32DSP,
Jack Carter5dc8ac92013-09-25 23:50:44 +0000320 Kind_COP2,
321 Kind_MSA128BRegs,
322 Kind_MSA128HRegs,
323 Kind_MSA128WRegs,
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000324 Kind_MSA128DRegs,
325 Kind_MSA128CtrlRegs
Jack Carter873c7242013-01-12 01:03:14 +0000326 };
327
328private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000329 enum KindTy {
330 k_CondCode,
331 k_CoprocNum,
332 k_Immediate,
333 k_Memory,
334 k_PostIndexRegister,
335 k_Register,
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000336 k_PtrReg,
Matheus Almeida779c5932013-11-18 12:32:49 +0000337 k_Token,
338 k_LSAImm
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000339 } Kind;
340
341 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
Jack Carterb4dbc172012-09-05 23:34:03 +0000342
Eric Christopher8996c5d2013-03-15 00:42:55 +0000343 struct Token {
344 const char *Data;
345 unsigned Length;
346 };
347
348 struct RegOp {
349 unsigned RegNum;
350 RegisterKind Kind;
351 };
352
353 struct ImmOp {
354 const MCExpr *Val;
355 };
356
357 struct MemOp {
358 unsigned Base;
359 const MCExpr *Off;
360 };
361
Jack Carterb4dbc172012-09-05 23:34:03 +0000362 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000363 struct Token Tok;
364 struct RegOp Reg;
365 struct ImmOp Imm;
366 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000367 };
368
369 SMLoc StartLoc, EndLoc;
370
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000371public:
372 void addRegOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000373 assert(N == 1 && "Invalid number of operands!");
374 Inst.addOperand(MCOperand::CreateReg(getReg()));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000375 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000376
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000377 void addPtrRegOperands(MCInst &Inst, unsigned N) const {
378 assert(N == 1 && "Invalid number of operands!");
379 Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
380 }
381
Vladimir Medic4c299852013-11-06 11:27:05 +0000382 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000383 // Add as immediate when possible. Null MCExpr = 0.
384 if (Expr == 0)
385 Inst.addOperand(MCOperand::CreateImm(0));
386 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
387 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
388 else
389 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000390 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000391
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000392 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000393 assert(N == 1 && "Invalid number of operands!");
394 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000395 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000396 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000397
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000398 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000399 assert(N == 2 && "Invalid number of operands!");
400
401 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
402
403 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000404 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000405 }
406
407 bool isReg() const { return Kind == k_Register; }
408 bool isImm() const { return Kind == k_Immediate; }
409 bool isToken() const { return Kind == k_Token; }
410 bool isMem() const { return Kind == k_Memory; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000411 bool isPtrReg() const { return Kind == k_PtrReg; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000412 bool isInvNum() const { return Kind == k_Immediate; }
Matheus Almeida779c5932013-11-18 12:32:49 +0000413 bool isLSAImm() const { return Kind == k_LSAImm; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000414
415 StringRef getToken() const {
416 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000417 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000418 }
419
420 unsigned getReg() const {
421 assert((Kind == k_Register) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000422 return Reg.RegNum;
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000423 }
424
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000425 unsigned getPtrReg() const {
426 assert((Kind == k_PtrReg) && "Invalid access!");
427 return Reg.RegNum;
428 }
429
Jack Carter873c7242013-01-12 01:03:14 +0000430 void setRegKind(RegisterKind RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000431 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
Jack Carter873c7242013-01-12 01:03:14 +0000432 Reg.Kind = RegKind;
433 }
434
Jack Carterb4dbc172012-09-05 23:34:03 +0000435 const MCExpr *getImm() const {
Matheus Almeida779c5932013-11-18 12:32:49 +0000436 assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000437 return Imm.Val;
438 }
439
Jack Carterdc1e35d2012-09-06 20:00:02 +0000440 unsigned getMemBase() const {
441 assert((Kind == k_Memory) && "Invalid access!");
442 return Mem.Base;
443 }
444
445 const MCExpr *getMemOff() const {
446 assert((Kind == k_Memory) && "Invalid access!");
447 return Mem.Off;
448 }
449
Jack Carterb4dbc172012-09-05 23:34:03 +0000450 static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
451 MipsOperand *Op = new MipsOperand(k_Token);
452 Op->Tok.Data = Str.data();
453 Op->Tok.Length = Str.size();
454 Op->StartLoc = S;
455 Op->EndLoc = S;
456 return Op;
457 }
458
459 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
460 MipsOperand *Op = new MipsOperand(k_Register);
461 Op->Reg.RegNum = RegNum;
462 Op->StartLoc = S;
463 Op->EndLoc = E;
464 return Op;
465 }
466
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000467 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
468 MipsOperand *Op = new MipsOperand(k_PtrReg);
469 Op->Reg.RegNum = RegNum;
470 Op->StartLoc = S;
471 Op->EndLoc = E;
472 return Op;
473 }
474
Jack Carterb4dbc172012-09-05 23:34:03 +0000475 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
476 MipsOperand *Op = new MipsOperand(k_Immediate);
477 Op->Imm.Val = Val;
478 Op->StartLoc = S;
479 Op->EndLoc = E;
480 return Op;
481 }
482
Matheus Almeida779c5932013-11-18 12:32:49 +0000483 static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
484 MipsOperand *Op = new MipsOperand(k_LSAImm);
485 Op->Imm.Val = Val;
486 Op->StartLoc = S;
487 Op->EndLoc = E;
488 return Op;
489 }
490
Jack Carter3b2c96e2014-01-22 23:31:38 +0000491 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
492 SMLoc E) {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000493 MipsOperand *Op = new MipsOperand(k_Memory);
494 Op->Mem.Base = Base;
495 Op->Mem.Off = Off;
496 Op->StartLoc = S;
497 Op->EndLoc = E;
498 return Op;
499 }
500
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000501 bool isGPR32Asm() const {
502 return Kind == k_Register && Reg.Kind == Kind_GPR32;
Jack Carter873c7242013-01-12 01:03:14 +0000503 }
Vladimir Medicc6960592013-06-19 10:14:36 +0000504 void addRegAsmOperands(MCInst &Inst, unsigned N) const {
Jack Carter873c7242013-01-12 01:03:14 +0000505 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
506 }
507
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +0000508 bool isGPR64Asm() const {
509 return Kind == k_Register && Reg.Kind == Kind_GPR64;
Jack Carter873c7242013-01-12 01:03:14 +0000510 }
Jack Carter873c7242013-01-12 01:03:14 +0000511
512 bool isHWRegsAsm() const {
513 assert((Kind == k_Register) && "Invalid access!");
514 return Reg.Kind == Kind_HWRegs;
515 }
Jack Carter873c7242013-01-12 01:03:14 +0000516
Jack Carter873c7242013-01-12 01:03:14 +0000517 bool isCCRAsm() const {
518 assert((Kind == k_Register) && "Invalid access!");
519 return Reg.Kind == Kind_CCRRegs;
520 }
521
Vladimir Medic4c299852013-11-06 11:27:05 +0000522 bool isAFGR64Asm() const {
Vladimir Medic233dd512013-06-24 10:05:34 +0000523 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
524 }
525
526 bool isFGR64Asm() const {
527 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
528 }
529
530 bool isFGR32Asm() const {
531 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
532 }
533
Akira Hatanaka14e31a22013-08-20 22:58:56 +0000534 bool isFGRH32Asm() const {
535 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
536 }
537
Vladimir Medic643b3982013-07-30 10:12:14 +0000538 bool isFCCRegsAsm() const {
539 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
540 }
541
Akira Hatanaka00fcf2e2013-08-08 21:54:26 +0000542 bool isACC64DSPAsm() const {
543 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
Akira Hatanaka34a32c02013-08-06 22:20:40 +0000544 }
545
Akira Hatanakafeb7ee82013-08-14 01:02:20 +0000546 bool isLO32DSPAsm() const {
547 return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
548 }
549
550 bool isHI32DSPAsm() const {
551 return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
552 }
553
Vladimir Medic4c299852013-11-06 11:27:05 +0000554 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
Vladimir Medic05bcde62013-09-16 10:29:42 +0000555
Jack Carter5dc8ac92013-09-25 23:50:44 +0000556 bool isMSA128BAsm() const {
557 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
558 }
559
560 bool isMSA128HAsm() const {
561 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
562 }
563
564 bool isMSA128WAsm() const {
565 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
566 }
567
568 bool isMSA128DAsm() const {
569 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
570 }
571
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000572 bool isMSA128CRAsm() const {
573 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
574 }
575
Jack Carterb4dbc172012-09-05 23:34:03 +0000576 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000577 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000578 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000579 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000580
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000581 virtual void print(raw_ostream &OS) const {
582 llvm_unreachable("unimplemented!");
583 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000584}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000585} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000586
Jack Carter9e65aa32013-03-22 00:05:30 +0000587namespace llvm {
588extern const MCInstrDesc MipsInsts[];
589}
590static const MCInstrDesc &getInstDesc(unsigned Opcode) {
591 return MipsInsts[Opcode];
592}
593
594bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000595 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000596 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000597
Jack Carter9e65aa32013-03-22 00:05:30 +0000598 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000599
600 if (MCID.isBranch() || MCID.isCall()) {
601 const unsigned Opcode = Inst.getOpcode();
602 MCOperand Offset;
603
604 switch (Opcode) {
605 default:
606 break;
607 case Mips::BEQ:
608 case Mips::BNE:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000609 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000610 Offset = Inst.getOperand(2);
611 if (!Offset.isImm())
612 break; // We'll deal with this situation later on when applying fixups.
613 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
614 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000615 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000616 return Error(IDLoc, "branch to misaligned address");
617 break;
618 case Mips::BGEZ:
619 case Mips::BGTZ:
620 case Mips::BLEZ:
621 case Mips::BLTZ:
622 case Mips::BGEZAL:
623 case Mips::BLTZAL:
624 case Mips::BC1F:
625 case Mips::BC1T:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000626 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000627 Offset = Inst.getOperand(1);
628 if (!Offset.isImm())
629 break; // We'll deal with this situation later on when applying fixups.
630 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
631 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000632 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000633 return Error(IDLoc, "branch to misaligned address");
634 break;
635 }
636 }
637
Jack Carterc15c1d22013-04-25 23:31:35 +0000638 if (MCID.hasDelaySlot() && Options.isReorder()) {
639 // If this instruction has a delay slot and .set reorder is active,
640 // emit a NOP after it.
641 Instructions.push_back(Inst);
642 MCInst NopInst;
643 NopInst.setOpcode(Mips::SLL);
644 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
645 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
646 NopInst.addOperand(MCOperand::CreateImm(0));
647 Instructions.push_back(NopInst);
648 return false;
649 }
650
Jack Carter9e65aa32013-03-22 00:05:30 +0000651 if (MCID.mayLoad() || MCID.mayStore()) {
652 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000653 // reference or immediate we may have to expand instructions.
654 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000655 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000656 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
657 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000658 MCOperand &Op = Inst.getOperand(i);
659 if (Op.isImm()) {
660 int MemOffset = Op.getImm();
661 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000662 // Offset can't exceed 16bit value.
663 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000664 return false;
665 }
666 } else if (Op.isExpr()) {
667 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000668 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000669 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000670 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000671 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000672 // Expand symbol.
673 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000674 return false;
675 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000676 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000677 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000678 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000679 }
680 }
681 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000682 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000683 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000684
685 if (needsExpansion(Inst))
686 expandInstruction(Inst, IDLoc, Instructions);
687 else
688 Instructions.push_back(Inst);
689
690 return false;
691}
692
Jack Carter30a59822012-10-04 04:03:53 +0000693bool MipsAsmParser::needsExpansion(MCInst &Inst) {
694
Jack Carterd0bd6422013-04-18 00:41:53 +0000695 switch (Inst.getOpcode()) {
696 case Mips::LoadImm32Reg:
697 case Mips::LoadAddr32Imm:
698 case Mips::LoadAddr32Reg:
Daniel Sandersa771fef2014-03-24 14:05:39 +0000699 case Mips::SUBi:
700 case Mips::SUBiu:
701 case Mips::DSUBi:
702 case Mips::DSUBiu:
Jack Carterd0bd6422013-04-18 00:41:53 +0000703 return true;
704 default:
705 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000706 }
707}
Jack Carter92995f12012-10-06 00:53:28 +0000708
Jack Carter30a59822012-10-04 04:03:53 +0000709void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000710 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000711 switch (Inst.getOpcode()) {
712 case Mips::LoadImm32Reg:
713 return expandLoadImm(Inst, IDLoc, Instructions);
714 case Mips::LoadAddr32Imm:
715 return expandLoadAddressImm(Inst, IDLoc, Instructions);
716 case Mips::LoadAddr32Reg:
717 return expandLoadAddressReg(Inst, IDLoc, Instructions);
Daniel Sandersa771fef2014-03-24 14:05:39 +0000718 case Mips::SUBi:
719 Instructions.push_back(MCInstBuilder(Mips::ADDi)
720 .addReg(Inst.getOperand(0).getReg())
721 .addReg(Inst.getOperand(1).getReg())
722 .addImm(-Inst.getOperand(2).getImm()));
723 return;
724 case Mips::SUBiu:
725 Instructions.push_back(MCInstBuilder(Mips::ADDiu)
726 .addReg(Inst.getOperand(0).getReg())
727 .addReg(Inst.getOperand(1).getReg())
728 .addImm(-Inst.getOperand(2).getImm()));
729 return;
730 case Mips::DSUBi:
731 Instructions.push_back(MCInstBuilder(Mips::DADDi)
732 .addReg(Inst.getOperand(0).getReg())
733 .addReg(Inst.getOperand(1).getReg())
734 .addImm(-Inst.getOperand(2).getImm()));
735 return;
736 case Mips::DSUBiu:
737 Instructions.push_back(MCInstBuilder(Mips::DADDiu)
738 .addReg(Inst.getOperand(0).getReg())
739 .addReg(Inst.getOperand(1).getReg())
740 .addImm(-Inst.getOperand(2).getImm()));
741 return;
Jack Carterd0bd6422013-04-18 00:41:53 +0000742 }
Jack Carter30a59822012-10-04 04:03:53 +0000743}
Jack Carter92995f12012-10-06 00:53:28 +0000744
Jack Carter30a59822012-10-04 04:03:53 +0000745void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000746 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000747 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000748 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000749 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000750 const MCOperand &RegOp = Inst.getOperand(0);
751 assert(RegOp.isReg() && "expected register operand kind");
752
753 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000754 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000755 if (0 <= ImmValue && ImmValue <= 65535) {
756 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000757 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000758 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000759 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000760 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000761 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000762 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000763 } else if (ImmValue < 0 && ImmValue >= -32768) {
764 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000765 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000766 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000767 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000768 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000769 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000770 Instructions.push_back(tmpInst);
771 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000772 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000773 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000774 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000775 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000776 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
777 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000778 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000779 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000780 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000781 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
782 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
783 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
784 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000785 Instructions.push_back(tmpInst);
786 }
787}
Jack Carter92995f12012-10-06 00:53:28 +0000788
Vladimir Medic4c299852013-11-06 11:27:05 +0000789void
790MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
791 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000792 MCInst tmpInst;
793 const MCOperand &ImmOp = Inst.getOperand(2);
794 assert(ImmOp.isImm() && "expected immediate operand kind");
795 const MCOperand &SrcRegOp = Inst.getOperand(1);
796 assert(SrcRegOp.isReg() && "expected register operand kind");
797 const MCOperand &DstRegOp = Inst.getOperand(0);
798 assert(DstRegOp.isReg() && "expected register operand kind");
799 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000800 if (-32768 <= ImmValue && ImmValue <= 65535) {
801 // For -32768 <= j <= 65535.
802 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000803 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +0000804 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
805 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
806 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
807 Instructions.push_back(tmpInst);
808 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000809 // For any other value of j that is representable as a 32-bit integer.
810 // la d,j(s) => lui d,hi16(j)
811 // ori d,d,lo16(j)
812 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +0000813 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000814 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
815 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
816 Instructions.push_back(tmpInst);
817 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000818 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000819 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
820 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
821 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
822 Instructions.push_back(tmpInst);
823 tmpInst.clear();
824 tmpInst.setOpcode(Mips::ADDu);
825 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
826 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
827 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
828 Instructions.push_back(tmpInst);
829 }
830}
831
Vladimir Medic4c299852013-11-06 11:27:05 +0000832void
833MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
834 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000835 MCInst tmpInst;
836 const MCOperand &ImmOp = Inst.getOperand(1);
837 assert(ImmOp.isImm() && "expected immediate operand kind");
838 const MCOperand &RegOp = Inst.getOperand(0);
839 assert(RegOp.isReg() && "expected register operand kind");
840 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000841 if (-32768 <= ImmValue && ImmValue <= 65535) {
842 // For -32768 <= j <= 65535.
843 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +0000844 tmpInst.setOpcode(Mips::ADDiu);
845 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000846 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +0000847 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
848 Instructions.push_back(tmpInst);
849 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000850 // For any other value of j that is representable as a 32-bit integer.
851 // la d,j => lui d,hi16(j)
852 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000853 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +0000854 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
855 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
856 Instructions.push_back(tmpInst);
857 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000858 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +0000859 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
860 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
861 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
862 Instructions.push_back(tmpInst);
863 }
864}
865
Jack Carter9e65aa32013-03-22 00:05:30 +0000866void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000867 SmallVectorImpl<MCInst> &Instructions,
868 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000869 const MCSymbolRefExpr *SR;
870 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +0000871 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +0000872 const MCExpr *ExprOffset;
873 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +0000874 unsigned AtRegNum = getReg(
875 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +0000876 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000877 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
878 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000879 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +0000880 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
881 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +0000882 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +0000883 if (isImmOpnd) {
884 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
885 ImmOffset = Inst.getOperand(2).getImm();
886 LoOffset = ImmOffset & 0x0000ffff;
887 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +0000888 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +0000889 if (LoOffset & 0x8000)
890 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +0000891 } else
Jack Carter9e65aa32013-03-22 00:05:30 +0000892 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000893 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +0000894 TempInst.setLoc(IDLoc);
895 // 1st instruction in expansion is LUi. For load instruction we can use
896 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +0000897 // but for stores we must use $at.
898 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +0000899 TempInst.setOpcode(Mips::LUi);
900 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
901 if (isImmOpnd)
902 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
903 else {
904 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +0000905 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +0000906 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
907 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
908 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000909 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000910 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000911 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +0000912 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000913 }
914 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000915 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +0000916 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000917 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +0000918 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +0000919 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000920 TempInst.setOpcode(Mips::ADDu);
921 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
922 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
923 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
924 Instructions.push_back(TempInst);
925 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +0000926 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +0000927 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +0000928 TempInst.setOpcode(Inst.getOpcode());
929 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
930 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
931 if (isImmOpnd)
932 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
933 else {
934 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000935 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
936 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
937 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +0000938 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +0000939 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000940 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +0000941 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +0000942 }
943 }
944 Instructions.push_back(TempInst);
945 TempInst.clear();
946}
947
Vladimir Medic4c299852013-11-06 11:27:05 +0000948bool MipsAsmParser::MatchAndEmitInstruction(
949 SMLoc IDLoc, unsigned &Opcode,
950 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
951 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000952 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +0000953 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +0000954 unsigned MatchResult =
955 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +0000956
957 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000958 default:
959 break;
Jack Carterb4dbc172012-09-05 23:34:03 +0000960 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +0000961 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +0000962 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +0000963 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +0000964 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +0000965 return false;
966 }
967 case Match_MissingFeature:
968 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
969 return true;
970 case Match_InvalidOperand: {
971 SMLoc ErrorLoc = IDLoc;
972 if (ErrorInfo != ~0U) {
973 if (ErrorInfo >= Operands.size())
974 return Error(IDLoc, "too few operands for instruction");
975
Vladimir Medic4c299852013-11-06 11:27:05 +0000976 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +0000977 if (ErrorLoc == SMLoc())
978 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +0000979 }
980
981 return Error(ErrorLoc, "invalid operand for instruction");
982 }
983 case Match_MnemonicFail:
984 return Error(IDLoc, "invalid instruction");
985 }
Rafael Espindola870c4e92012-01-11 03:56:41 +0000986 return true;
987}
988
Daniel Sandersb1d7e532014-03-25 11:16:03 +0000989void MipsAsmParser::warnIfAssemblerTemporary(int RegNo) {
990 if ((RegNo != 0) && ((int)Options.getATRegNum() == RegNo)) {
991 if (RegNo == 1)
992 Warning(getLexer().getLoc(), "Used $at without \".set noat\"");
993 else
994 Warning(getLexer().getLoc(), Twine("Used $") + Twine(RegNo) +
995 " with \".set at=$" + Twine(RegNo) +
996 "\"");
997 }
998}
999
Jack Carter1ac53222013-02-20 23:11:17 +00001000int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001001 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +00001002
Vladimir Medic4c299852013-11-06 11:27:05 +00001003 CC = StringSwitch<unsigned>(Name)
1004 .Case("zero", 0)
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001005 .Case("at", 1)
Vladimir Medic4c299852013-11-06 11:27:05 +00001006 .Case("a0", 4)
1007 .Case("a1", 5)
1008 .Case("a2", 6)
1009 .Case("a3", 7)
1010 .Case("v0", 2)
1011 .Case("v1", 3)
1012 .Case("s0", 16)
1013 .Case("s1", 17)
1014 .Case("s2", 18)
1015 .Case("s3", 19)
1016 .Case("s4", 20)
1017 .Case("s5", 21)
1018 .Case("s6", 22)
1019 .Case("s7", 23)
1020 .Case("k0", 26)
1021 .Case("k1", 27)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001022 .Case("gp", 28)
Vladimir Medic4c299852013-11-06 11:27:05 +00001023 .Case("sp", 29)
1024 .Case("fp", 30)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001025 .Case("s8", 30)
Vladimir Medic4c299852013-11-06 11:27:05 +00001026 .Case("ra", 31)
1027 .Case("t0", 8)
1028 .Case("t1", 9)
1029 .Case("t2", 10)
1030 .Case("t3", 11)
1031 .Case("t4", 12)
1032 .Case("t5", 13)
1033 .Case("t6", 14)
1034 .Case("t7", 15)
1035 .Case("t8", 24)
1036 .Case("t9", 25)
1037 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001038
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001039 if (isN32() || isN64()) {
1040 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1041 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1042 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1043 if (8 <= CC && CC <= 11)
1044 CC += 4;
Jack Carter1ac53222013-02-20 23:11:17 +00001045
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001046 if (CC == -1)
1047 CC = StringSwitch<unsigned>(Name)
1048 .Case("a4", 8)
1049 .Case("a5", 9)
1050 .Case("a6", 10)
1051 .Case("a7", 11)
1052 .Case("kt0", 26)
1053 .Case("kt1", 27)
1054 .Default(-1);
1055 }
Jack Carter1ac53222013-02-20 23:11:17 +00001056
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001057 warnIfAssemblerTemporary(CC);
Daniel Sanderse231ae92014-03-25 10:57:07 +00001058
Jack Carter1ac53222013-02-20 23:11:17 +00001059 return CC;
1060}
Jack Carterd0bd6422013-04-18 00:41:53 +00001061
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001062int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001063
Jack Cartera63b16a2012-09-07 00:23:42 +00001064 if (Name[0] == 'f') {
1065 StringRef NumString = Name.substr(1);
1066 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001067 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001068 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001069 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001070 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001071 return IntVal;
1072 }
1073 return -1;
1074}
Jack Cartera63b16a2012-09-07 00:23:42 +00001075
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001076int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1077
1078 if (Name.startswith("fcc")) {
1079 StringRef NumString = Name.substr(3);
1080 unsigned IntVal;
1081 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001082 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001083 if (IntVal > 7) // There are only 8 fcc registers.
1084 return -1;
1085 return IntVal;
1086 }
1087 return -1;
1088}
1089
1090int MipsAsmParser::matchACRegisterName(StringRef Name) {
1091
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001092 if (Name.startswith("ac")) {
1093 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001094 unsigned IntVal;
1095 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001096 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001097 if (IntVal > 3) // There are only 3 acc registers.
1098 return -1;
1099 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001100 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001101 return -1;
1102}
Jack Carterd0bd6422013-04-18 00:41:53 +00001103
Jack Carter5dc8ac92013-09-25 23:50:44 +00001104int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1105 unsigned IntVal;
1106
1107 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1108 return -1;
1109
1110 if (IntVal > 31)
1111 return -1;
1112
1113 return IntVal;
1114}
1115
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001116int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1117 int CC;
1118
1119 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001120 .Case("msair", 0)
1121 .Case("msacsr", 1)
1122 .Case("msaaccess", 2)
1123 .Case("msasave", 3)
1124 .Case("msamodify", 4)
1125 .Case("msarequest", 5)
1126 .Case("msamap", 6)
1127 .Case("msaunmap", 7)
1128 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001129
1130 return CC;
1131}
1132
Vladimir Medic8cd17102013-06-20 11:21:49 +00001133int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1134
Vladimir Medic8cd17102013-06-20 11:21:49 +00001135 int CC;
1136 CC = matchCPURegisterName(Name);
1137 if (CC != -1)
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00001138 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1139 : Mips::GPR32RegClassID);
Jack Carter5dc8ac92013-09-25 23:50:44 +00001140 CC = matchFPURegisterName(Name);
Vladimir Medic4c299852013-11-06 11:27:05 +00001141 // TODO: decide about fpu register class
Jack Carter5dc8ac92013-09-25 23:50:44 +00001142 if (CC != -1)
1143 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1144 : Mips::FGR32RegClassID);
1145 return matchMSA128RegisterName(Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001146}
1147
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001148int MipsAsmParser::regKindToRegClass(int RegKind) {
Jack Cartera63b16a2012-09-07 00:23:42 +00001149
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001150 switch (RegKind) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001151 case MipsOperand::Kind_GPR32:
1152 return Mips::GPR32RegClassID;
1153 case MipsOperand::Kind_GPR64:
1154 return Mips::GPR64RegClassID;
1155 case MipsOperand::Kind_HWRegs:
1156 return Mips::HWRegsRegClassID;
1157 case MipsOperand::Kind_FGR32Regs:
1158 return Mips::FGR32RegClassID;
1159 case MipsOperand::Kind_FGRH32Regs:
1160 return Mips::FGRH32RegClassID;
1161 case MipsOperand::Kind_FGR64Regs:
1162 return Mips::FGR64RegClassID;
1163 case MipsOperand::Kind_AFGR64Regs:
1164 return Mips::AFGR64RegClassID;
1165 case MipsOperand::Kind_CCRRegs:
1166 return Mips::CCRRegClassID;
1167 case MipsOperand::Kind_ACC64DSP:
1168 return Mips::ACC64DSPRegClassID;
1169 case MipsOperand::Kind_FCCRegs:
1170 return Mips::FCCRegClassID;
1171 case MipsOperand::Kind_MSA128BRegs:
1172 return Mips::MSA128BRegClassID;
1173 case MipsOperand::Kind_MSA128HRegs:
1174 return Mips::MSA128HRegClassID;
1175 case MipsOperand::Kind_MSA128WRegs:
1176 return Mips::MSA128WRegClassID;
1177 case MipsOperand::Kind_MSA128DRegs:
1178 return Mips::MSA128DRegClassID;
1179 case MipsOperand::Kind_MSA128CtrlRegs:
1180 return Mips::MSACtrlRegClassID;
1181 default:
1182 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001183 }
Jack Cartera63b16a2012-09-07 00:23:42 +00001184}
Jack Carterb4dbc172012-09-05 23:34:03 +00001185
Jack Carter0b744b32012-10-04 02:29:46 +00001186bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1187 if (Reg > 31)
1188 return false;
1189
1190 aTReg = Reg;
1191 return true;
1192}
1193
Daniel Sandersd89b1362014-03-24 16:48:01 +00001194int MipsAsmParser::getATReg() {
1195 int AT = Options.getATRegNum();
1196 if (AT == 0)
1197 TokError("Pseudo instruction requires $at, which is not available");
1198 return AT;
1199}
Jack Carter0b744b32012-10-04 02:29:46 +00001200
Jack Carterd0bd6422013-04-18 00:41:53 +00001201unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001202 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001203}
1204
Jack Carter873c7242013-01-12 01:03:14 +00001205int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001206 if (RegNum >
Vladimir Medic4c299852013-11-06 11:27:05 +00001207 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
Jack Carterb4dbc172012-09-05 23:34:03 +00001208 return -1;
1209
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001210 if (RegClass == Mips::GPR32RegClassID || RegClass == Mips::GPR64RegClassID)
1211 warnIfAssemblerTemporary(RegNum);
1212
Jack Carter873c7242013-01-12 01:03:14 +00001213 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001214}
1215
Jack Carter873c7242013-01-12 01:03:14 +00001216int MipsAsmParser::tryParseRegister(bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001217 const AsmToken &Tok = Parser.getTok();
1218 int RegNum = -1;
1219
1220 if (Tok.is(AsmToken::Identifier)) {
1221 std::string lowerCase = Tok.getString().lower();
Jack Carter873c7242013-01-12 01:03:14 +00001222 RegNum = matchRegisterName(lowerCase, is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001223 } else if (Tok.is(AsmToken::Integer))
Jack Carter30a59822012-10-04 04:03:53 +00001224 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Vladimir Medic4c299852013-11-06 11:27:05 +00001225 is64BitReg ? Mips::GPR64RegClassID
1226 : Mips::GPR32RegClassID);
Jack Carterb4dbc172012-09-05 23:34:03 +00001227 return RegNum;
1228}
1229
Jack Carterd0bd6422013-04-18 00:41:53 +00001230bool MipsAsmParser::tryParseRegisterOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001231 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001232
1233 SMLoc S = Parser.getTok().getLoc();
1234 int RegNo = -1;
Jack Cartera63b16a2012-09-07 00:23:42 +00001235
Jack Carter873c7242013-01-12 01:03:14 +00001236 RegNo = tryParseRegister(is64BitReg);
Jack Carterb4dbc172012-09-05 23:34:03 +00001237 if (RegNo == -1)
1238 return true;
1239
Vladimir Medic4c299852013-11-06 11:27:05 +00001240 Operands.push_back(
1241 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
Jack Carterb4dbc172012-09-05 23:34:03 +00001242 Parser.Lex(); // Eat register token.
1243 return false;
1244}
1245
Vladimir Medic4c299852013-11-06 11:27:05 +00001246bool
1247MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1248 StringRef Mnemonic) {
Jack Carter30a59822012-10-04 04:03:53 +00001249 // Check if the current operand has a custom associated parser, if so, try to
1250 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001251 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1252 if (ResTy == MatchOperand_Success)
1253 return false;
1254 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1255 // there was a match, but an error occurred, in which case, just return that
1256 // the operand parsing failed.
1257 if (ResTy == MatchOperand_ParseFail)
1258 return true;
1259
1260 switch (getLexer().getKind()) {
1261 default:
1262 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1263 return true;
1264 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001265 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001266 SMLoc S = Parser.getTok().getLoc();
1267 Parser.Lex(); // Eat dollar token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001268 // Parse the register operand.
Jack Carter873c7242013-01-12 01:03:14 +00001269 if (!tryParseRegisterOperand(Operands, isMips64())) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001270 if (getLexer().is(AsmToken::LParen)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001271 // Check if it is indexed addressing operand.
Jack Carterb4dbc172012-09-05 23:34:03 +00001272 Operands.push_back(MipsOperand::CreateToken("(", S));
Jack Carterd0bd6422013-04-18 00:41:53 +00001273 Parser.Lex(); // Eat the parenthesis.
Jack Carterb4dbc172012-09-05 23:34:03 +00001274 if (getLexer().isNot(AsmToken::Dollar))
1275 return true;
1276
Jack Carterd0bd6422013-04-18 00:41:53 +00001277 Parser.Lex(); // Eat the dollar
Jack Carter873c7242013-01-12 01:03:14 +00001278 if (tryParseRegisterOperand(Operands, isMips64()))
Jack Carterb4dbc172012-09-05 23:34:03 +00001279 return true;
1280
1281 if (!getLexer().is(AsmToken::RParen))
1282 return true;
1283
1284 S = Parser.getTok().getLoc();
1285 Operands.push_back(MipsOperand::CreateToken(")", S));
1286 Parser.Lex();
1287 }
1288 return false;
1289 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001290 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001291 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001292 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001293 return true;
1294
Jack Carter873c7242013-01-12 01:03:14 +00001295 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001296 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001297 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001298 const MCExpr *Res =
1299 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001300
1301 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1302 return false;
1303 }
1304 case AsmToken::Identifier:
Vladimir Medic77ffd7a2013-11-13 09:48:53 +00001305 // For instruction aliases like "bc1f $Label" dedicated parser will
1306 // eat the '$' sign before failing. So in order to look for appropriate
1307 // label we must check first if we have already consumed '$'.
1308 if (hasConsumedDollar) {
1309 hasConsumedDollar = false;
1310 SMLoc S = Parser.getTok().getLoc();
1311 StringRef Identifier;
1312 if (Parser.parseIdentifier(Identifier))
1313 return true;
1314 SMLoc E =
1315 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1316 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1317 // Create a symbol reference.
1318 const MCExpr *Res =
1319 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1320
1321 Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1322 return false;
1323 }
Jack Carterd76b2372013-03-21 21:44:16 +00001324 // Look for the existing symbol, we should check if
Matheus Almeidad534fc32014-01-30 13:40:26 +00001325 // we need to assign the proper RegisterKind.
Jack Carterd0bd6422013-04-18 00:41:53 +00001326 if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1327 return false;
Vladimir Medic4c299852013-11-06 11:27:05 +00001328 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001329 case AsmToken::LParen:
1330 case AsmToken::Minus:
1331 case AsmToken::Plus:
1332 case AsmToken::Integer:
1333 case AsmToken::String: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001334 // Quoted label names.
Jack Carterb4dbc172012-09-05 23:34:03 +00001335 const MCExpr *IdVal;
1336 SMLoc S = Parser.getTok().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001337 if (getParser().parseExpression(IdVal))
Jack Carterb4dbc172012-09-05 23:34:03 +00001338 return true;
Jack Carter873c7242013-01-12 01:03:14 +00001339 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001340 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1341 return false;
1342 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001343 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001344 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001345 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001346 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001347 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001348 return true;
1349
Jack Carter873c7242013-01-12 01:03:14 +00001350 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1351
Jack Carterdc1e35d2012-09-06 20:00:02 +00001352 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1353 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001354 } // case AsmToken::Percent
1355 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001356 return true;
1357}
1358
Vladimir Medic4c299852013-11-06 11:27:05 +00001359const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001360 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001361 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001362 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001363 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001364 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001365 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001366 short Val = MCE->getValue();
1367 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001368 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001369 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001370 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001371 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001372 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001373 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001374 if (LoSign)
1375 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001376 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001377 } else {
1378 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001379 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001380 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001381 }
1382
Jack Carterb5cf5902013-04-17 00:18:04 +00001383 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001384 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001385 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001386 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001387 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001388 return Res;
1389 }
1390
1391 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001392 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1393
1394 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1395 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1396 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1397 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1398 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1399 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1400 return MipsMCExpr::CreateHi(Expr, getContext());
1401 return MipsMCExpr::CreateLo(Expr, getContext());
1402 }
1403
Jack Carterd0bd6422013-04-18 00:41:53 +00001404 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1405 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001406 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1407 return Res;
1408 }
1409
1410 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001411 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1412 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1413 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001414 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001415 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001416 return Expr;
1417}
1418
1419bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1420
1421 switch (Expr->getKind()) {
1422 case MCExpr::Constant:
1423 return true;
1424 case MCExpr::SymbolRef:
1425 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1426 case MCExpr::Binary:
1427 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1428 if (!isEvaluated(BE->getLHS()))
1429 return false;
1430 return isEvaluated(BE->getRHS());
1431 }
1432 case MCExpr::Unary:
1433 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001434 case MCExpr::Target:
1435 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001436 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001437 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001438}
Jack Carterd0bd6422013-04-18 00:41:53 +00001439
Jack Carterb5cf5902013-04-17 00:18:04 +00001440bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001441 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001442 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001443 if (Tok.isNot(AsmToken::Identifier))
1444 return true;
1445
1446 std::string Str = Tok.getIdentifier().str();
1447
Jack Carterd0bd6422013-04-18 00:41:53 +00001448 Parser.Lex(); // Eat the identifier.
1449 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001450 const MCExpr *IdVal;
1451 SMLoc EndLoc;
1452
1453 if (getLexer().getKind() == AsmToken::LParen) {
1454 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001455 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001456 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001457 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001458 const AsmToken &nextTok = Parser.getTok();
1459 if (nextTok.isNot(AsmToken::Identifier))
1460 return true;
1461 Str += "(%";
1462 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001463 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001464 if (getLexer().getKind() != AsmToken::LParen)
1465 return true;
1466 } else
1467 break;
1468 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001469 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001470 return true;
1471
1472 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001473 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001474
1475 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001476 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001477
Jack Carterd0bd6422013-04-18 00:41:53 +00001478 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001479 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001480}
1481
Jack Carterb4dbc172012-09-05 23:34:03 +00001482bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1483 SMLoc &EndLoc) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001484 StartLoc = Parser.getTok().getLoc();
Jack Carter873c7242013-01-12 01:03:14 +00001485 RegNo = tryParseRegister(isMips64());
1486 EndLoc = Parser.getTok().getLoc();
Vladimir Medic4c299852013-11-06 11:27:05 +00001487 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001488}
1489
Jack Carterb5cf5902013-04-17 00:18:04 +00001490bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001491 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001492 bool Result = true;
1493
1494 while (getLexer().getKind() == AsmToken::LParen)
1495 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001496
Jack Carterd0bd6422013-04-18 00:41:53 +00001497 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001498 default:
1499 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001500 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001501 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001502 case AsmToken::Integer:
1503 case AsmToken::Minus:
1504 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001505 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001506 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001507 else
1508 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001509 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001510 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001511 break;
Jack Carter873c7242013-01-12 01:03:14 +00001512 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001513 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001514 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001515 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001516}
1517
Jack Carterb4dbc172012-09-05 23:34:03 +00001518MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001519 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001520
1521 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001522 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001523 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001524 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001525 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001526 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001527
Jack Carterb5cf5902013-04-17 00:18:04 +00001528 if (getLexer().getKind() == AsmToken::LParen) {
1529 Parser.Lex();
1530 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001531 }
1532
Jack Carterb5cf5902013-04-17 00:18:04 +00001533 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001534 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001535 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001536
Jack Carterd0bd6422013-04-18 00:41:53 +00001537 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001538 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001539 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001540 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001541 SMLoc E =
1542 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001543 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1544 return MatchOperand_Success;
1545 }
1546 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001547 SMLoc E =
1548 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001549
Jack Carterd0bd6422013-04-18 00:41:53 +00001550 // Zero register assumed, add a memory operand with ZERO as its base.
Vladimir Medic4c299852013-11-06 11:27:05 +00001551 Operands.push_back(MipsOperand::CreateMem(
1552 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
Jack Carterb5cf5902013-04-17 00:18:04 +00001553 return MatchOperand_Success;
1554 }
1555 Error(Parser.getTok().getLoc(), "'(' expected");
1556 return MatchOperand_ParseFail;
1557 }
1558
Jack Carterd0bd6422013-04-18 00:41:53 +00001559 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001560 }
1561
Vladimir Medic4c299852013-11-06 11:27:05 +00001562 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1563 : (int)MipsOperand::Kind_GPR32);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001564 if (Res != MatchOperand_Success)
1565 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001566
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001567 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001568 Error(Parser.getTok().getLoc(), "')' expected");
1569 return MatchOperand_ParseFail;
1570 }
1571
Jack Carter873c7242013-01-12 01:03:14 +00001572 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1573
Jack Carterd0bd6422013-04-18 00:41:53 +00001574 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001575
1576 if (IdVal == 0)
1577 IdVal = MCConstantExpr::Create(0, getContext());
1578
Jack Carterd0bd6422013-04-18 00:41:53 +00001579 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001580 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001581 int RegNo = op->getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001582 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001583 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001584 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001585 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1586 int64_t Imm;
1587 if (IdVal->EvaluateAsAbsolute(Imm))
1588 IdVal = MCConstantExpr::Create(Imm, getContext());
1589 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1590 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1591 getContext());
1592 }
1593
Jack Carterdc1e35d2012-09-06 20:00:02 +00001594 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1595 delete op;
Jack Carterb4dbc172012-09-05 23:34:03 +00001596 return MatchOperand_Success;
1597}
1598
Vladimir Medic4c299852013-11-06 11:27:05 +00001599bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1600 int RegKind) {
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001601 // If the first token is not '$' we have an error.
1602 if (Parser.getTok().isNot(AsmToken::Dollar))
1603 return false;
1604
1605 SMLoc S = Parser.getTok().getLoc();
1606 Parser.Lex();
1607 AsmToken::TokenKind TkKind = getLexer().getKind();
1608 int Reg;
1609
1610 if (TkKind == AsmToken::Integer) {
1611 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1612 regKindToRegClass(RegKind));
1613 if (Reg == -1)
1614 return false;
1615 } else if (TkKind == AsmToken::Identifier) {
1616 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1617 return false;
1618 Reg = getReg(regKindToRegClass(RegKind), Reg);
1619 } else {
1620 return false;
1621 }
1622
1623 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1624 Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1625 Operands.push_back(Op);
1626 Parser.Lex();
1627 return true;
1628}
1629
1630MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001631MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1632 MipsOperand::RegisterKind RegKind =
1633 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +00001634
1635 // Parse index register.
1636 if (!parsePtrReg(Operands, RegKind))
1637 return MatchOperand_NoMatch;
1638
1639 // Parse '('.
1640 if (Parser.getTok().isNot(AsmToken::LParen))
1641 return MatchOperand_NoMatch;
1642
1643 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1644 Parser.Lex();
1645
1646 // Parse base register.
1647 if (!parsePtrReg(Operands, RegKind))
1648 return MatchOperand_NoMatch;
1649
1650 // Parse ')'.
1651 if (Parser.getTok().isNot(AsmToken::RParen))
1652 return MatchOperand_NoMatch;
1653
1654 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1655 Parser.Lex();
1656
1657 return MatchOperand_Success;
1658}
1659
Jack Carter873c7242013-01-12 01:03:14 +00001660MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001661MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Vladimir Medic8cd17102013-06-20 11:21:49 +00001662 int RegKind) {
1663 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
Vladimir Medic4c299852013-11-06 11:27:05 +00001664 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001665 if (searchSymbolAlias(Operands, Kind))
Jack Carterd76b2372013-03-21 21:44:16 +00001666 return MatchOperand_Success;
1667 return MatchOperand_NoMatch;
1668 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001669 SMLoc S = Parser.getTok().getLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001670 // If the first token is not '$', we have an error.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001671 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
Jack Carter873c7242013-01-12 01:03:14 +00001672 return MatchOperand_NoMatch;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001673 if (!hasConsumedDollar) {
1674 Parser.Lex(); // Eat the '$'
1675 hasConsumedDollar = true;
1676 }
1677 if (getLexer().getKind() == AsmToken::Identifier) {
1678 int RegNum = -1;
1679 std::string RegName = Parser.getTok().getString().lower();
Vladimir Medic4c299852013-11-06 11:27:05 +00001680 // Match register by name
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001681 switch (RegKind) {
1682 case MipsOperand::Kind_GPR32:
1683 case MipsOperand::Kind_GPR64:
1684 RegNum = matchCPURegisterName(RegName);
1685 break;
1686 case MipsOperand::Kind_AFGR64Regs:
1687 case MipsOperand::Kind_FGR64Regs:
1688 case MipsOperand::Kind_FGR32Regs:
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001689 case MipsOperand::Kind_FGRH32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001690 RegNum = matchFPURegisterName(RegName);
1691 if (RegKind == MipsOperand::Kind_AFGR64Regs)
1692 RegNum /= 2;
Vladimir Medic4c299852013-11-06 11:27:05 +00001693 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1694 if (RegNum != -1 && RegNum % 2 != 0)
Vladimir Medic65cd5742013-09-10 09:50:01 +00001695 Warning(S, "Float register should be even.");
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001696 break;
1697 case MipsOperand::Kind_FCCRegs:
1698 RegNum = matchFCCRegisterName(RegName);
1699 break;
1700 case MipsOperand::Kind_ACC64DSP:
1701 RegNum = matchACRegisterName(RegName);
1702 break;
Vladimir Medic4c299852013-11-06 11:27:05 +00001703 default:
1704 break; // No match, value is set to -1.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001705 }
1706 // No match found, return _NoMatch to give a chance to other round.
1707 if (RegNum < 0)
1708 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001709
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001710 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1711 if (RegVal == -1)
1712 return MatchOperand_NoMatch;
1713
Vladimir Medic4c299852013-11-06 11:27:05 +00001714 MipsOperand *Op =
1715 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001716 Op->setRegKind(Kind);
1717 Operands.push_back(Op);
1718 hasConsumedDollar = false;
1719 Parser.Lex(); // Eat the register name.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001720 return MatchOperand_Success;
1721 } else if (getLexer().getKind() == AsmToken::Integer) {
1722 unsigned RegNum = Parser.getTok().getIntVal();
1723 if (Kind == MipsOperand::Kind_HWRegs) {
1724 if (RegNum != 29)
1725 return MatchOperand_NoMatch;
1726 // Only hwreg 29 is supported, found at index 0.
1727 RegNum = 0;
1728 }
1729 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1730 if (Reg == -1)
1731 return MatchOperand_NoMatch;
1732 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1733 Op->setRegKind(Kind);
1734 Operands.push_back(Op);
1735 hasConsumedDollar = false;
1736 Parser.Lex(); // Eat the register number.
Vladimir Medic4c299852013-11-06 11:27:05 +00001737 if ((RegKind == MipsOperand::Kind_GPR32) &&
1738 (getLexer().is(AsmToken::LParen))) {
Vladimir Medic3467b902013-07-18 09:28:35 +00001739 // Check if it is indexed addressing operand.
1740 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1741 Parser.Lex(); // Eat the parenthesis.
Vladimir Medic4c299852013-11-06 11:27:05 +00001742 if (parseRegs(Operands, RegKind) != MatchOperand_Success)
Vladimir Medic3467b902013-07-18 09:28:35 +00001743 return MatchOperand_NoMatch;
1744 if (getLexer().isNot(AsmToken::RParen))
1745 return MatchOperand_NoMatch;
1746 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1747 Parser.Lex();
1748 }
Jack Carter873c7242013-01-12 01:03:14 +00001749 return MatchOperand_Success;
1750 }
1751 return MatchOperand_NoMatch;
1752}
Vladimir Medic64828a12013-07-16 10:07:14 +00001753
Matheus Almeidab74293d2013-10-14 11:49:30 +00001754bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1755 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1756
1757 if (Val < 0)
1758 return false;
1759
1760 switch (Kind) {
1761 default:
1762 return false;
1763 case MipsOperand::Kind_MSA128BRegs:
1764 return Val < 16;
1765 case MipsOperand::Kind_MSA128HRegs:
1766 return Val < 8;
1767 case MipsOperand::Kind_MSA128WRegs:
1768 return Val < 4;
1769 case MipsOperand::Kind_MSA128DRegs:
1770 return Val < 2;
1771 }
1772}
1773
Vladimir Medic8cd17102013-06-20 11:21:49 +00001774MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001775MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Jack Carter5dc8ac92013-09-25 23:50:44 +00001776 int RegKind) {
1777 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1778 SMLoc S = Parser.getTok().getLoc();
1779 std::string RegName;
1780
1781 if (Parser.getTok().isNot(AsmToken::Dollar))
1782 return MatchOperand_NoMatch;
1783
1784 switch (RegKind) {
1785 default:
1786 return MatchOperand_ParseFail;
1787 case MipsOperand::Kind_MSA128BRegs:
1788 case MipsOperand::Kind_MSA128HRegs:
1789 case MipsOperand::Kind_MSA128WRegs:
1790 case MipsOperand::Kind_MSA128DRegs:
1791 break;
1792 }
1793
1794 Parser.Lex(); // Eat the '$'.
1795 if (getLexer().getKind() == AsmToken::Identifier)
1796 RegName = Parser.getTok().getString().lower();
1797 else
1798 return MatchOperand_ParseFail;
1799
1800 int RegNum = matchMSA128RegisterName(RegName);
1801
1802 if (RegNum < 0 || RegNum > 31)
1803 return MatchOperand_ParseFail;
1804
1805 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1806 if (RegVal == -1)
1807 return MatchOperand_ParseFail;
1808
Vladimir Medic4c299852013-11-06 11:27:05 +00001809 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Jack Carter5dc8ac92013-09-25 23:50:44 +00001810 Op->setRegKind(Kind);
1811 Operands.push_back(Op);
1812
1813 Parser.Lex(); // Eat the register identifier.
1814
Matheus Almeidab74293d2013-10-14 11:49:30 +00001815 // MSA registers may be suffixed with an index in the form of:
1816 // 1) Immediate expression.
1817 // 2) General Purpose Register.
1818 // Examples:
1819 // 1) copy_s.b $29,$w0[0]
1820 // 2) sld.b $w0,$w1[$1]
1821
1822 if (Parser.getTok().isNot(AsmToken::LBrac))
1823 return MatchOperand_Success;
1824
1825 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1826
1827 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1828 Parser.Lex(); // Parse the '[' token.
1829
1830 if (Parser.getTok().is(AsmToken::Dollar)) {
1831 // This must be a GPR.
1832 MipsOperand *RegOp;
1833 SMLoc VIdx = Parser.getTok().getLoc();
1834 Parser.Lex(); // Parse the '$' token.
1835
1836 // GPR have aliases and we must account for that. Example: $30 == $fp
1837 if (getLexer().getKind() == AsmToken::Integer) {
1838 unsigned RegNum = Parser.getTok().getIntVal();
1839 int Reg = matchRegisterByNumber(
1840 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1841 if (Reg == -1) {
1842 Error(VIdx, "invalid general purpose register");
1843 return MatchOperand_ParseFail;
1844 }
1845
1846 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1847 } else if (getLexer().getKind() == AsmToken::Identifier) {
1848 int RegNum = -1;
1849 std::string RegName = Parser.getTok().getString().lower();
1850
1851 RegNum = matchCPURegisterName(RegName);
1852 if (RegNum == -1) {
1853 Error(VIdx, "general purpose register expected");
1854 return MatchOperand_ParseFail;
1855 }
1856 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1857 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1858 } else
1859 return MatchOperand_ParseFail;
1860
1861 RegOp->setRegKind(MipsOperand::Kind_GPR32);
1862 Operands.push_back(RegOp);
1863 Parser.Lex(); // Eat the register identifier.
1864
1865 if (Parser.getTok().isNot(AsmToken::RBrac))
1866 return MatchOperand_ParseFail;
1867
1868 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1869 Parser.Lex(); // Parse the ']' token.
1870
1871 return MatchOperand_Success;
1872 }
1873
1874 // The index must be a constant expression then.
1875 SMLoc VIdx = Parser.getTok().getLoc();
1876 const MCExpr *ImmVal;
1877
1878 if (getParser().parseExpression(ImmVal))
1879 return MatchOperand_ParseFail;
1880
1881 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1882 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1883 Error(VIdx, "invalid immediate value");
1884 return MatchOperand_ParseFail;
1885 }
1886
1887 SMLoc E = Parser.getTok().getEndLoc();
1888
1889 if (Parser.getTok().isNot(AsmToken::RBrac))
1890 return MatchOperand_ParseFail;
1891
Vladimir Medic4c299852013-11-06 11:27:05 +00001892 bool insve =
1893 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1894 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
Matheus Almeidab74293d2013-10-14 11:49:30 +00001895
1896 // The second vector index of insve instructions is always 0.
1897 if (insve && Operands.size() > 6) {
1898 if (expr->getValue() != 0) {
1899 Error(VIdx, "immediate value must be 0");
1900 return MatchOperand_ParseFail;
1901 }
1902 Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1903 } else
1904 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1905
1906 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1907
1908 Parser.Lex(); // Parse the ']' token.
1909
Jack Carter5dc8ac92013-09-25 23:50:44 +00001910 return MatchOperand_Success;
1911}
1912
1913MipsAsmParser::OperandMatchResultTy
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001914MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1915 int RegKind) {
1916 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1917
1918 if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1919 return MatchOperand_NoMatch;
1920
1921 if (Parser.getTok().isNot(AsmToken::Dollar))
1922 return MatchOperand_ParseFail;
1923
1924 SMLoc S = Parser.getTok().getLoc();
1925
1926 Parser.Lex(); // Eat the '$' symbol.
1927
1928 int RegNum = -1;
1929 if (getLexer().getKind() == AsmToken::Identifier)
1930 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1931 else if (getLexer().getKind() == AsmToken::Integer)
1932 RegNum = Parser.getTok().getIntVal();
1933 else
1934 return MatchOperand_ParseFail;
1935
1936 if (RegNum < 0 || RegNum > 7)
1937 return MatchOperand_ParseFail;
1938
1939 int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1940 if (RegVal == -1)
1941 return MatchOperand_ParseFail;
1942
Vladimir Medic4c299852013-11-06 11:27:05 +00001943 MipsOperand *RegOp =
1944 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001945 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1946 Operands.push_back(RegOp);
1947 Parser.Lex(); // Eat the register identifier.
1948
1949 return MatchOperand_Success;
1950}
1951
1952MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001953MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic8cd17102013-06-20 11:21:49 +00001954
1955 if (!isMips64())
1956 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001957 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001958}
1959
1960MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001961MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1962 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
Vladimir Medic8cd17102013-06-20 11:21:49 +00001963}
Jack Carter873c7242013-01-12 01:03:14 +00001964
Vladimir Medic4c299852013-11-06 11:27:05 +00001965MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1966 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001967
1968 if (isFP64())
1969 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001970 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001971}
1972
1973MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001974MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic233dd512013-06-24 10:05:34 +00001975 if (!isFP64())
1976 return MatchOperand_NoMatch;
Vladimir Medic4c299852013-11-06 11:27:05 +00001977 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001978}
1979
1980MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001981MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1982 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1983}
1984
1985MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1986 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1987 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
Vladimir Medic233dd512013-06-24 10:05:34 +00001988}
1989
Vladimir Medic643b3982013-07-30 10:12:14 +00001990MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001991MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1992 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
Akira Hatanaka14e31a22013-08-20 22:58:56 +00001993}
1994
1995MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001996MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1997 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
Vladimir Medic643b3982013-07-30 10:12:14 +00001998}
1999
Akira Hatanaka34a32c02013-08-06 22:20:40 +00002000MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002001MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00002002 // If the first token is not '$' we have an error.
2003 if (Parser.getTok().isNot(AsmToken::Dollar))
2004 return MatchOperand_NoMatch;
2005
2006 SMLoc S = Parser.getTok().getLoc();
2007 Parser.Lex(); // Eat the '$'
2008
2009 const AsmToken &Tok = Parser.getTok(); // Get next token.
2010
2011 if (Tok.isNot(AsmToken::Identifier))
2012 return MatchOperand_NoMatch;
2013
2014 if (!Tok.getIdentifier().startswith("ac"))
2015 return MatchOperand_NoMatch;
2016
2017 StringRef NumString = Tok.getIdentifier().substr(2);
2018
2019 unsigned IntVal;
2020 if (NumString.getAsInteger(10, IntVal))
2021 return MatchOperand_NoMatch;
2022
2023 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
2024
2025 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2026 Op->setRegKind(MipsOperand::Kind_LO32DSP);
2027 Operands.push_back(Op);
2028
2029 Parser.Lex(); // Eat the register number.
2030 return MatchOperand_Success;
2031}
2032
2033MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002034MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Akira Hatanakafeb7ee82013-08-14 01:02:20 +00002035 // If the first token is not '$' we have an error.
2036 if (Parser.getTok().isNot(AsmToken::Dollar))
2037 return MatchOperand_NoMatch;
2038
2039 SMLoc S = Parser.getTok().getLoc();
2040 Parser.Lex(); // Eat the '$'
2041
2042 const AsmToken &Tok = Parser.getTok(); // Get next token.
2043
2044 if (Tok.isNot(AsmToken::Identifier))
2045 return MatchOperand_NoMatch;
2046
2047 if (!Tok.getIdentifier().startswith("ac"))
2048 return MatchOperand_NoMatch;
2049
2050 StringRef NumString = Tok.getIdentifier().substr(2);
2051
2052 unsigned IntVal;
2053 if (NumString.getAsInteger(10, IntVal))
2054 return MatchOperand_NoMatch;
2055
2056 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
2057
2058 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2059 Op->setRegKind(MipsOperand::Kind_HI32DSP);
2060 Operands.push_back(Op);
2061
2062 Parser.Lex(); // Eat the register number.
2063 return MatchOperand_Success;
2064}
2065
Vladimir Medic05bcde62013-09-16 10:29:42 +00002066MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002067MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic05bcde62013-09-16 10:29:42 +00002068 // If the first token is not '$' we have an error.
2069 if (Parser.getTok().isNot(AsmToken::Dollar))
2070 return MatchOperand_NoMatch;
2071
2072 SMLoc S = Parser.getTok().getLoc();
2073 Parser.Lex(); // Eat the '$'
2074
2075 const AsmToken &Tok = Parser.getTok(); // Get next token.
2076
2077 if (Tok.isNot(AsmToken::Integer))
2078 return MatchOperand_NoMatch;
2079
2080 unsigned IntVal = Tok.getIntVal();
2081
2082 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
2083
2084 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
2085 Op->setRegKind(MipsOperand::Kind_COP2);
2086 Operands.push_back(Op);
2087
2088 Parser.Lex(); // Eat the register number.
2089 return MatchOperand_Success;
2090}
2091
Vladimir Medic4c299852013-11-06 11:27:05 +00002092MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
2093 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2094 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002095}
2096
Vladimir Medic4c299852013-11-06 11:27:05 +00002097MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
2098 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2099 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002100}
2101
Vladimir Medic4c299852013-11-06 11:27:05 +00002102MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
2103 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2104 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002105}
2106
Vladimir Medic4c299852013-11-06 11:27:05 +00002107MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
2108 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2109 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
Jack Carter5dc8ac92013-09-25 23:50:44 +00002110}
2111
Vladimir Medic4c299852013-11-06 11:27:05 +00002112MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
2113 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2114 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00002115}
2116
Jack Carterd0bd6422013-04-18 00:41:53 +00002117bool MipsAsmParser::searchSymbolAlias(
Vladimir Medic4c299852013-11-06 11:27:05 +00002118 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
Jack Carterd76b2372013-03-21 21:44:16 +00002119
2120 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2121 if (Sym) {
2122 SMLoc S = Parser.getTok().getLoc();
2123 const MCExpr *Expr;
2124 if (Sym->isVariable())
2125 Expr = Sym->getVariableValue();
2126 else
2127 return false;
2128 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00002129 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
2130 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00002131 const StringRef DefSymbol = Ref->getSymbol().getName();
2132 if (DefSymbol.startswith("$")) {
Jack Carter02593002013-05-28 22:21:05 +00002133 int RegNum = -1;
2134 APInt IntVal(32, -1);
2135 if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
2136 RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
Vladimir Medic4c299852013-11-06 11:27:05 +00002137 isMips64() ? Mips::GPR64RegClassID
2138 : Mips::GPR32RegClassID);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002139 else {
2140 // Lookup for the register with the corresponding name.
2141 switch (Kind) {
2142 case MipsOperand::Kind_AFGR64Regs:
2143 case MipsOperand::Kind_FGR64Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002144 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002145 break;
2146 case MipsOperand::Kind_FGR32Regs:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002147 RegNum = matchFPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002148 break;
Akira Hatanaka13e6ccf2013-08-06 23:08:38 +00002149 case MipsOperand::Kind_GPR64:
2150 case MipsOperand::Kind_GPR32:
Vladimir Medic8cd17102013-06-20 11:21:49 +00002151 default:
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002152 RegNum = matchCPURegisterName(DefSymbol.substr(1));
Vladimir Medic8cd17102013-06-20 11:21:49 +00002153 break;
2154 }
Vladimir Medic27c87ea2013-08-13 13:07:09 +00002155 if (RegNum > -1)
2156 RegNum = getReg(regKindToRegClass(Kind), RegNum);
Vladimir Medic8cd17102013-06-20 11:21:49 +00002157 }
Jack Carterd76b2372013-03-21 21:44:16 +00002158 if (RegNum > -1) {
2159 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002160 MipsOperand *op =
2161 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
Vladimir Medic8cd17102013-06-20 11:21:49 +00002162 op->setRegKind(Kind);
Jack Carterd76b2372013-03-21 21:44:16 +00002163 Operands.push_back(op);
2164 return true;
2165 }
2166 }
2167 } else if (Expr->getKind() == MCExpr::Constant) {
2168 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00002169 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2170 MipsOperand *op =
2171 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
Jack Carterd76b2372013-03-21 21:44:16 +00002172 Operands.push_back(op);
2173 return true;
2174 }
2175 }
2176 return false;
2177}
Jack Carterd0bd6422013-04-18 00:41:53 +00002178
Jack Carter873c7242013-01-12 01:03:14 +00002179MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002180MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2181 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002182}
2183
2184MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002185MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2186 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
Jack Carter873c7242013-01-12 01:03:14 +00002187}
2188
Vladimir Medic2b953d02013-10-01 09:48:56 +00002189MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00002190MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00002191 const MCExpr *IdVal;
2192 // If the first token is '$' we may have register operand.
2193 if (Parser.getTok().is(AsmToken::Dollar))
2194 return MatchOperand_NoMatch;
2195 SMLoc S = Parser.getTok().getLoc();
2196 if (getParser().parseExpression(IdVal))
2197 return MatchOperand_ParseFail;
2198 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00002199 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00002200 int64_t Val = MCE->getValue();
2201 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2202 Operands.push_back(MipsOperand::CreateImm(
Vladimir Medic4c299852013-11-06 11:27:05 +00002203 MCConstantExpr::Create(0 - Val, getContext()), S, E));
Vladimir Medic2b953d02013-10-01 09:48:56 +00002204 return MatchOperand_Success;
2205}
2206
Matheus Almeida779c5932013-11-18 12:32:49 +00002207MipsAsmParser::OperandMatchResultTy
2208MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2209 switch (getLexer().getKind()) {
2210 default:
2211 return MatchOperand_NoMatch;
2212 case AsmToken::LParen:
2213 case AsmToken::Plus:
2214 case AsmToken::Minus:
2215 case AsmToken::Integer:
2216 break;
2217 }
2218
2219 const MCExpr *Expr;
2220 SMLoc S = Parser.getTok().getLoc();
2221
2222 if (getParser().parseExpression(Expr))
2223 return MatchOperand_ParseFail;
2224
2225 int64_t Val;
2226 if (!Expr->EvaluateAsAbsolute(Val)) {
2227 Error(S, "expected immediate value");
2228 return MatchOperand_ParseFail;
2229 }
2230
2231 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2232 // and because the CPU always adds one to the immediate field, the allowed
2233 // range becomes 1..4. We'll only check the range here and will deal
2234 // with the addition/subtraction when actually decoding/encoding
2235 // the instruction.
2236 if (Val < 1 || Val > 4) {
2237 Error(S, "immediate not in range (1..4)");
2238 return MatchOperand_ParseFail;
2239 }
2240
Jack Carter3b2c96e2014-01-22 23:31:38 +00002241 Operands.push_back(
2242 MipsOperand::CreateLSAImm(Expr, S, Parser.getTok().getLoc()));
Matheus Almeida779c5932013-11-18 12:32:49 +00002243 return MatchOperand_Success;
2244}
2245
Jack Carterdc1e35d2012-09-06 20:00:02 +00002246MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2247
Vladimir Medic4c299852013-11-06 11:27:05 +00002248 MCSymbolRefExpr::VariantKind VK =
2249 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2250 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2251 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2252 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2253 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2254 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2255 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2256 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2257 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2258 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2259 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2260 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2261 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2262 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2263 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2264 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2265 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2266 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2267 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00002268
2269 return VK;
2270}
Jack Cartera63b16a2012-09-07 00:23:42 +00002271
Vladimir Medic4c299852013-11-06 11:27:05 +00002272bool MipsAsmParser::ParseInstruction(
2273 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2274 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002275 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002276 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002277 Parser.eatToEndOfStatement();
2278 return Error(NameLoc, "Unknown instruction");
2279 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002280 // First operand in MCInst is instruction mnemonic.
2281 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
Jack Carterb4dbc172012-09-05 23:34:03 +00002282
2283 // Read the remaining operands.
2284 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2285 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002286 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002287 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002288 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002289 return Error(Loc, "unexpected token in argument list");
2290 }
2291
Jack Carterd0bd6422013-04-18 00:41:53 +00002292 while (getLexer().is(AsmToken::Comma)) {
2293 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002294 // Parse and remember the operand.
2295 if (ParseOperand(Operands, Name)) {
2296 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002297 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002298 return Error(Loc, "unexpected token in argument list");
2299 }
2300 }
2301 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002302 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2303 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002304 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002305 return Error(Loc, "unexpected token in argument list");
2306 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002307 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002308 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002309}
2310
Jack Carter0b744b32012-10-04 02:29:46 +00002311bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002312 SMLoc Loc = getLexer().getLoc();
2313 Parser.eatToEndOfStatement();
2314 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002315}
2316
2317bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002318 // Line should look like: ".set noat".
2319 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002320 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002321 // eat noat
2322 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002323 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2325 reportParseError("unexpected token in statement");
2326 return false;
2327 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002328 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002329 return false;
2330}
Jack Carterd0bd6422013-04-18 00:41:53 +00002331
Jack Carter0b744b32012-10-04 02:29:46 +00002332bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002333 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002334 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002335 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002336 getParser().Lex();
2337 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002338 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002339 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002340 return false;
2341 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002342 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002343 if (getLexer().isNot(AsmToken::Dollar)) {
2344 reportParseError("unexpected token in statement");
2345 return false;
2346 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002347 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002348 const AsmToken &Reg = Parser.getTok();
2349 if (Reg.is(AsmToken::Identifier)) {
2350 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2351 } else if (Reg.is(AsmToken::Integer)) {
2352 AtRegNo = Reg.getIntVal();
2353 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002354 reportParseError("unexpected token in statement");
2355 return false;
2356 }
Jack Carter1ac53222013-02-20 23:11:17 +00002357
Daniel Sanders71a89d922014-03-25 13:01:06 +00002358 if (AtRegNo < 0 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002359 reportParseError("unexpected token in statement");
2360 return false;
2361 }
2362
2363 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002364 reportParseError("unexpected token in statement");
2365 return false;
2366 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002367 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002368
2369 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2370 reportParseError("unexpected token in statement");
2371 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002372 }
2373 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002374 return false;
2375 } else {
2376 reportParseError("unexpected token in statement");
2377 return false;
2378 }
2379}
2380
2381bool MipsAsmParser::parseSetReorderDirective() {
2382 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002383 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002384 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2385 reportParseError("unexpected token in statement");
2386 return false;
2387 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002388 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002389 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002390 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002391 return false;
2392}
2393
2394bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002395 Parser.Lex();
2396 // If this is not the end of the statement, report an error.
2397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2398 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002399 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002400 }
2401 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002402 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002403 Parser.Lex(); // Consume the EndOfStatement.
2404 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002405}
2406
2407bool MipsAsmParser::parseSetMacroDirective() {
2408 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002409 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2411 reportParseError("unexpected token in statement");
2412 return false;
2413 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002414 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002415 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002416 return false;
2417}
2418
2419bool MipsAsmParser::parseSetNoMacroDirective() {
2420 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002421 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2423 reportParseError("`noreorder' must be set before `nomacro'");
2424 return false;
2425 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002426 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002427 reportParseError("`noreorder' must be set before `nomacro'");
2428 return false;
2429 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002430 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002431 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002432 return false;
2433}
Jack Carterd76b2372013-03-21 21:44:16 +00002434
Jack Carter39536722014-01-22 23:08:42 +00002435bool MipsAsmParser::parseSetNoMips16Directive() {
2436 Parser.Lex();
2437 // If this is not the end of the statement, report an error.
2438 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2439 reportParseError("unexpected token in statement");
2440 return false;
2441 }
2442 // For now do nothing.
2443 Parser.Lex(); // Consume the EndOfStatement.
2444 return false;
2445}
2446
Jack Carterd76b2372013-03-21 21:44:16 +00002447bool MipsAsmParser::parseSetAssignment() {
2448 StringRef Name;
2449 const MCExpr *Value;
2450
2451 if (Parser.parseIdentifier(Name))
2452 reportParseError("expected identifier after .set");
2453
2454 if (getLexer().isNot(AsmToken::Comma))
2455 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002456 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002457
Jack Carter3b2c96e2014-01-22 23:31:38 +00002458 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002459 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002460
Jack Carterd0bd6422013-04-18 00:41:53 +00002461 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002462 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002463 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002464 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002465 Sym = getContext().GetOrCreateSymbol(Name);
2466 Sym->setVariableValue(Value);
2467
2468 return false;
2469}
Jack Carterd0bd6422013-04-18 00:41:53 +00002470
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002471bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2472 Parser.Lex();
2473 if (getLexer().isNot(AsmToken::EndOfStatement))
2474 return reportParseError("unexpected token in .set directive");
2475
2476 switch(Feature) {
2477 default: llvm_unreachable("Unimplemented feature");
2478 case Mips::FeatureDSP:
2479 setFeatureBits(Mips::FeatureDSP, "dsp");
2480 getTargetStreamer().emitDirectiveSetDsp();
2481 break;
2482 case Mips::FeatureMicroMips:
2483 getTargetStreamer().emitDirectiveSetMicroMips();
2484 break;
2485 case Mips::FeatureMips16:
2486 getTargetStreamer().emitDirectiveSetMips16();
2487 break;
2488 case Mips::FeatureMips32r2:
2489 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2490 getTargetStreamer().emitDirectiveSetMips32R2();
2491 break;
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002492 case Mips::FeatureMips64:
2493 setFeatureBits(Mips::FeatureMips64, "mips64");
2494 getTargetStreamer().emitDirectiveSetMips64();
2495 break;
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002496 case Mips::FeatureMips64r2:
2497 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2498 getTargetStreamer().emitDirectiveSetMips64R2();
2499 break;
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002500 }
2501 return false;
2502}
2503
Jack Carter0b744b32012-10-04 02:29:46 +00002504bool MipsAsmParser::parseDirectiveSet() {
2505
Jack Carterd0bd6422013-04-18 00:41:53 +00002506 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002507 const AsmToken &Tok = Parser.getTok();
2508
2509 if (Tok.getString() == "noat") {
2510 return parseSetNoAtDirective();
2511 } else if (Tok.getString() == "at") {
2512 return parseSetAtDirective();
2513 } else if (Tok.getString() == "reorder") {
2514 return parseSetReorderDirective();
2515 } else if (Tok.getString() == "noreorder") {
2516 return parseSetNoReorderDirective();
2517 } else if (Tok.getString() == "macro") {
2518 return parseSetMacroDirective();
2519 } else if (Tok.getString() == "nomacro") {
2520 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002521 } else if (Tok.getString() == "mips16") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002522 return parseSetFeature(Mips::FeatureMips16);
Jack Carter0b744b32012-10-04 02:29:46 +00002523 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002524 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002525 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002526 getTargetStreamer().emitDirectiveSetNoMicroMips();
2527 Parser.eatToEndOfStatement();
2528 return false;
2529 } else if (Tok.getString() == "micromips") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002530 return parseSetFeature(Mips::FeatureMicroMips);
Vladimir Medic615b26e2014-03-04 09:54:09 +00002531 } else if (Tok.getString() == "mips32r2") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002532 return parseSetFeature(Mips::FeatureMips32r2);
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002533 } else if (Tok.getString() == "mips64") {
2534 return parseSetFeature(Mips::FeatureMips64);
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002535 } else if (Tok.getString() == "mips64r2") {
2536 return parseSetFeature(Mips::FeatureMips64r2);
Vladimir Medic27c398e2014-03-05 11:05:09 +00002537 } else if (Tok.getString() == "dsp") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002538 return parseSetFeature(Mips::FeatureDSP);
Jack Carterd76b2372013-03-21 21:44:16 +00002539 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002540 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002541 parseSetAssignment();
2542 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002543 }
Jack Carter07c818d2013-01-25 01:31:34 +00002544
Jack Carter0b744b32012-10-04 02:29:46 +00002545 return true;
2546}
2547
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002548/// parseDataDirective
Jack Carter07c818d2013-01-25 01:31:34 +00002549/// ::= .word [ expression (, expression)* ]
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002550bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
Jack Carter07c818d2013-01-25 01:31:34 +00002551 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2552 for (;;) {
2553 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002554 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002555 return true;
2556
2557 getParser().getStreamer().EmitValue(Value, Size);
2558
2559 if (getLexer().is(AsmToken::EndOfStatement))
2560 break;
2561
2562 // FIXME: Improve diagnostic.
2563 if (getLexer().isNot(AsmToken::Comma))
2564 return Error(L, "unexpected token in directive");
2565 Parser.Lex();
2566 }
2567 }
2568
2569 Parser.Lex();
2570 return false;
2571}
2572
Vladimir Medic4c299852013-11-06 11:27:05 +00002573/// parseDirectiveGpWord
2574/// ::= .gpword local_sym
2575bool MipsAsmParser::parseDirectiveGpWord() {
2576 const MCExpr *Value;
2577 // EmitGPRel32Value requires an expression, so we are using base class
2578 // method to evaluate the expression.
2579 if (getParser().parseExpression(Value))
2580 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002581 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002582
Vladimir Medice10c1122013-11-13 13:18:04 +00002583 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002584 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002585 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002586 return false;
2587}
2588
Jack Carter0cd3c192014-01-06 23:27:31 +00002589bool MipsAsmParser::parseDirectiveOption() {
2590 // Get the option token.
2591 AsmToken Tok = Parser.getTok();
2592 // At the moment only identifiers are supported.
2593 if (Tok.isNot(AsmToken::Identifier)) {
2594 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2595 Parser.eatToEndOfStatement();
2596 return false;
2597 }
2598
2599 StringRef Option = Tok.getIdentifier();
2600
2601 if (Option == "pic0") {
2602 getTargetStreamer().emitDirectiveOptionPic0();
2603 Parser.Lex();
2604 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2605 Error(Parser.getTok().getLoc(),
2606 "unexpected token in .option pic0 directive");
2607 Parser.eatToEndOfStatement();
2608 }
2609 return false;
2610 }
2611
Matheus Almeidaf79b2812014-03-26 13:40:29 +00002612 if (Option == "pic2") {
2613 getTargetStreamer().emitDirectiveOptionPic2();
2614 Parser.Lex();
2615 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2616 Error(Parser.getTok().getLoc(),
2617 "unexpected token in .option pic2 directive");
2618 Parser.eatToEndOfStatement();
2619 }
2620 return false;
2621 }
2622
Jack Carter0cd3c192014-01-06 23:27:31 +00002623 // Unknown option.
2624 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2625 Parser.eatToEndOfStatement();
2626 return false;
2627}
2628
Jack Carter0b744b32012-10-04 02:29:46 +00002629bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002630 StringRef IDVal = DirectiveID.getString();
2631
Matheus Almeidaab5633b2014-03-26 15:44:18 +00002632 if (IDVal == ".dword") {
2633 parseDataDirective(8, DirectiveID.getLoc());
2634 return false;
2635 }
2636
Jack Carterd0bd6422013-04-18 00:41:53 +00002637 if (IDVal == ".ent") {
2638 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002639 Parser.Lex();
2640 return false;
2641 }
2642
Jack Carter07c818d2013-01-25 01:31:34 +00002643 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002644 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002645 Parser.Lex();
2646 return false;
2647 }
2648
Jack Carter07c818d2013-01-25 01:31:34 +00002649 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002650 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002651 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002652 return false;
2653 }
2654
Jack Carter07c818d2013-01-25 01:31:34 +00002655 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002656 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002657 }
2658
Jack Carter07c818d2013-01-25 01:31:34 +00002659 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002660 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002661 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002662 return false;
2663 }
2664
Jack Carter07c818d2013-01-25 01:31:34 +00002665 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002666 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002667 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002668 return false;
2669 }
2670
Jack Carter07c818d2013-01-25 01:31:34 +00002671 if (IDVal == ".gpword") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002672 // Ignore this directive for now.
Vladimir Medic4c299852013-11-06 11:27:05 +00002673 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002674 return false;
2675 }
2676
Jack Carter07c818d2013-01-25 01:31:34 +00002677 if (IDVal == ".word") {
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002678 parseDataDirective(4, DirectiveID.getLoc());
Jack Carter07c818d2013-01-25 01:31:34 +00002679 return false;
2680 }
2681
Jack Carter0cd3c192014-01-06 23:27:31 +00002682 if (IDVal == ".option")
2683 return parseDirectiveOption();
2684
2685 if (IDVal == ".abicalls") {
2686 getTargetStreamer().emitDirectiveAbiCalls();
2687 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2688 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2689 // Clear line
2690 Parser.eatToEndOfStatement();
2691 }
2692 return false;
2693 }
2694
Rafael Espindola870c4e92012-01-11 03:56:41 +00002695 return true;
2696}
2697
Rafael Espindola870c4e92012-01-11 03:56:41 +00002698extern "C" void LLVMInitializeMipsAsmParser() {
2699 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2700 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2701 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2702 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2703}
Jack Carterb4dbc172012-09-05 23:34:03 +00002704
2705#define GET_REGISTER_MATCHER
2706#define GET_MATCHER_IMPLEMENTATION
2707#include "MipsGenAsmMatcher.inc"