blob: e1ebd7661c1c92c7b5ad414503fe1e49c039ccd8 [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"
Daniel Sandersb50ccf82014-04-01 10:35:28 +000026#include "llvm/Support/Debug.h"
Matheus Almeidae0d75aa2013-12-13 11:11:02 +000027#include "llvm/Support/MathExtras.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000028#include "llvm/Support/TargetRegistry.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000029
30using namespace llvm;
31
Joey Gouly0e76fa72013-09-12 10:28:05 +000032namespace llvm {
33class MCInstrInfo;
34}
35
Rafael Espindola870c4e92012-01-11 03:56:41 +000036namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000037class MipsAssemblerOptions {
38public:
Vladimir Medic4c299852013-11-06 11:27:05 +000039 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
Jack Carterb4dbc172012-09-05 23:34:03 +000040
Vladimir Medic4c299852013-11-06 11:27:05 +000041 unsigned getATRegNum() { return aTReg; }
Jack Carter0b744b32012-10-04 02:29:46 +000042 bool setATReg(unsigned Reg);
43
Vladimir Medic4c299852013-11-06 11:27:05 +000044 bool isReorder() { return reorder; }
45 void setReorder() { reorder = true; }
46 void setNoreorder() { reorder = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000047
Vladimir Medic4c299852013-11-06 11:27:05 +000048 bool isMacro() { return macro; }
49 void setMacro() { macro = true; }
50 void setNomacro() { macro = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000051
52private:
53 unsigned aTReg;
54 bool reorder;
55 bool macro;
56};
57}
58
59namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000060class MipsAsmParser : public MCTargetAsmParser {
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;
Jack Carter0b744b32012-10-04 02:29:46 +000069
Akira Hatanaka7605630c2012-08-17 20:16:42 +000070#define GET_ASSEMBLER_HEADER
71#include "MipsGenAsmMatcher.inc"
72
Chad Rosier49963552012-10-13 00:26:04 +000073 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Vladimir Medic4c299852013-11-06 11:27:05 +000074 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000075 MCStreamer &Out, unsigned &ErrorInfo,
76 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000077
Daniel Sandersb50ccf82014-04-01 10:35:28 +000078 /// Parse a register as used in CFI directives
Rafael Espindola870c4e92012-01-11 03:56:41 +000079 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
80
Daniel Sandersb50ccf82014-04-01 10:35:28 +000081 bool ParseParenSuffix(StringRef Name,
82 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
83
84 bool ParseBracketSuffix(StringRef Name,
85 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
86
Chad Rosierf0e87202012-10-25 20:41:34 +000087 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
88 SMLoc NameLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +000089 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000090
91 bool ParseDirective(AsmToken DirectiveID);
92
Jack Carterb4dbc172012-09-05 23:34:03 +000093 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000094 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000095
Daniel Sandersb50ccf82014-04-01 10:35:28 +000096 MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar(
97 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
98 SMLoc S);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000099
100 MipsAsmParser::OperandMatchResultTy
Daniel Sanders21bce302014-04-01 12:35:23 +0000101 MatchAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000102 SMLoc S);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000103
Jack Carter873c7242013-01-12 01:03:14 +0000104 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000105 ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000106
107 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000108 ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000109
110 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000111 ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000112
113 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000114 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic2b953d02013-10-01 09:48:56 +0000115
Matheus Almeida779c5932013-11-18 12:32:49 +0000116 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000117 ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeida779c5932013-11-18 12:32:49 +0000118
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000119 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carterd76b2372013-03-21 21:44:16 +0000120
Vladimir Medic4c299852013-11-06 11:27:05 +0000121 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
Jack Carterb4dbc172012-09-05 23:34:03 +0000122 StringRef Mnemonic);
123
Jack Carter30a59822012-10-04 04:03:53 +0000124 bool needsExpansion(MCInst &Inst);
125
126 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000127 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000128 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000129 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000130 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
131 SmallVectorImpl<MCInst> &Instructions);
132 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
133 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000134 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000135 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
136 bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000137 bool reportParseError(StringRef ErrorMsg);
138
Jack Carterb5cf5902013-04-17 00:18:04 +0000139 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000140 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000141
Vladimir Medic4c299852013-11-06 11:27:05 +0000142 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000143
144 bool isEvaluated(const MCExpr *Expr);
Matheus Almeidafe1e39d2014-03-26 14:26:27 +0000145 bool parseSetFeature(uint64_t Feature);
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000146 bool parseDirectiveCPSetup();
Jack Carter0b744b32012-10-04 02:29:46 +0000147 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000148 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000149
150 bool parseSetAtDirective();
151 bool parseSetNoAtDirective();
152 bool parseSetMacroDirective();
153 bool parseSetNoMacroDirective();
154 bool parseSetReorderDirective();
155 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000156 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000157
Jack Carterd76b2372013-03-21 21:44:16 +0000158 bool parseSetAssignment();
159
Matheus Almeida3e2a7022014-03-26 15:24:36 +0000160 bool parseDataDirective(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000161 bool parseDirectiveGpWord();
Rafael Espindola2378d4c2014-03-31 14:15:07 +0000162 bool parseDirectiveGpDWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000163
Jack Carterdc1e35d2012-09-06 20:00:02 +0000164 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000165
Daniel Sanders5e94e682014-03-27 16:42:17 +0000166 bool isGP64() const {
167 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
Jack Carterb4dbc172012-09-05 23:34:03 +0000168 }
169
Jack Cartera63b16a2012-09-07 00:23:42 +0000170 bool isFP64() const {
171 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
172 }
173
Daniel Sandersa4b0c742014-03-26 11:39:07 +0000174 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
Vladimir Medic4c299852013-11-06 11:27:05 +0000175 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000176
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000177 bool isMicroMips() const {
178 return STI.getFeatureBits() & Mips::FeatureMicroMips;
179 }
180
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000181 bool parseRegister(unsigned &RegNum);
182
183 bool eatComma(StringRef ErrorStr);
184
Jack Carter1ac53222013-02-20 23:11:17 +0000185 int matchCPURegisterName(StringRef Symbol);
186
Jack Carter873c7242013-01-12 01:03:14 +0000187 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000188
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000189 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000190
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000191 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000192
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000193 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000194
Jack Carter5dc8ac92013-09-25 23:50:44 +0000195 int matchMSA128RegisterName(StringRef Name);
196
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000197 int matchMSA128CtrlRegisterName(StringRef Name);
198
Jack Carterd0bd6422013-04-18 00:41:53 +0000199 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000200
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000201 unsigned getGPR(int RegNo);
202
Jack Carter1ac53222013-02-20 23:11:17 +0000203 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000204
205 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000206 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000207
208 // Helper function that checks if the value of a vector index is within the
209 // boundaries of accepted values for each RegisterKind
210 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
211 bool validateMSAIndex(int Val, int RegKind);
212
Vladimir Medic615b26e2014-03-04 09:54:09 +0000213 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
214 if (!(STI.getFeatureBits() & Feature)) {
215 setAvailableFeatures(ComputeAvailableFeatures(
216 STI.ToggleFeature(FeatureString)));
217 }
218 }
219
220 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
221 if (STI.getFeatureBits() & Feature) {
222 setAvailableFeatures(ComputeAvailableFeatures(
223 STI.ToggleFeature(FeatureString)));
224 }
225 }
226
Rafael Espindola870c4e92012-01-11 03:56:41 +0000227public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000228 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
229 const MCInstrInfo &MII)
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000230 : MCTargetAsmParser(), STI(sti), Parser(parser) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000231 // Initialize the set of available features.
232 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000233
234 // Assert exactly one ABI was chosen.
235 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
236 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
237 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
238 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000239 }
240
Jack Carterb4dbc172012-09-05 23:34:03 +0000241 MCAsmParser &getParser() const { return Parser; }
242 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000243
244 /// Warn if RegNo is the current assembler temporary.
245 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000246};
247}
248
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000249namespace {
250
251/// MipsOperand - Instances of this class represent a parsed Mips machine
252/// instruction.
253class MipsOperand : public MCParsedAsmOperand {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000254public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000255 /// Broad categories of register classes
256 /// The exact class is finalized by the render method.
257 enum RegKind {
258 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64())
259 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
260 /// isFP64())
261 RegKind_FCC = 4, /// FCC
262 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
263 RegKind_MSACtrl = 16, /// MSA control registers
264 RegKind_COP2 = 32, /// COP2
265 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
266 /// context).
267 RegKind_CCR = 128, /// CCR
268 RegKind_HWRegs = 256, /// HWRegs
269
270 /// Potentially any (e.g. $1)
271 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
272 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
273 RegKind_CCR | RegKind_HWRegs
Jack Carter873c7242013-01-12 01:03:14 +0000274 };
275
276private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000277 enum KindTy {
Daniel Sanders21bce302014-04-01 12:35:23 +0000278 k_Immediate, /// An immediate (possibly involving symbol references)
279 k_Memory, /// Base + Offset Memory Address
280 k_PhysRegister, /// A physical register from the Mips namespace
281 k_RegisterIndex, /// A register index in one or more RegKind.
282 k_Token /// A simple token
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000283 } Kind;
284
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000285 MipsOperand(KindTy K, MipsAsmParser &Parser)
286 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
287
288 /// For diagnostics, and checking the assembler temporary
289 MipsAsmParser &AsmParser;
Jack Carterb4dbc172012-09-05 23:34:03 +0000290
Eric Christopher8996c5d2013-03-15 00:42:55 +0000291 struct Token {
292 const char *Data;
293 unsigned Length;
294 };
295
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000296 struct PhysRegOp {
297 unsigned Num; /// Register Number
298 };
299
300 struct RegIdxOp {
301 unsigned Index; /// Index into the register class
302 RegKind Kind; /// Bitfield of the kinds it could possibly be
303 const MCRegisterInfo *RegInfo;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000304 };
305
306 struct ImmOp {
307 const MCExpr *Val;
308 };
309
310 struct MemOp {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000311 MipsOperand *Base;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000312 const MCExpr *Off;
313 };
314
Jack Carterb4dbc172012-09-05 23:34:03 +0000315 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000316 struct Token Tok;
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000317 struct PhysRegOp PhysReg;
318 struct RegIdxOp RegIdx;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000319 struct ImmOp Imm;
320 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000321 };
322
323 SMLoc StartLoc, EndLoc;
324
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000325 /// Internal constructor for register kinds
326 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
327 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
328 MipsAsmParser &Parser) {
329 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
330 Op->RegIdx.Index = Index;
331 Op->RegIdx.RegInfo = RegInfo;
332 Op->RegIdx.Kind = RegKind;
333 Op->StartLoc = S;
334 Op->EndLoc = E;
335 return Op;
336 }
337
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000338public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000339 /// Coerce the register to GPR32 and return the real register for the current
340 /// target.
341 unsigned getGPR32Reg() const {
342 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
343 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
344 unsigned ClassID = Mips::GPR32RegClassID;
345 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000346 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000347
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000348 /// Coerce the register to GPR64 and return the real register for the current
349 /// target.
350 unsigned getGPR64Reg() const {
351 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
352 unsigned ClassID = Mips::GPR64RegClassID;
353 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000354 }
355
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000356private:
357 /// Coerce the register to AFGR64 and return the real register for the current
358 /// target.
359 unsigned getAFGR64Reg() const {
360 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
361 if (RegIdx.Index % 2 != 0)
362 AsmParser.Warning(StartLoc, "Float register should be even.");
363 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
364 .getRegister(RegIdx.Index / 2);
365 }
366
367 /// Coerce the register to FGR64 and return the real register for the current
368 /// target.
369 unsigned getFGR64Reg() const {
370 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
371 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
372 .getRegister(RegIdx.Index);
373 }
374
375 /// Coerce the register to FGR32 and return the real register for the current
376 /// target.
377 unsigned getFGR32Reg() const {
378 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
379 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
380 .getRegister(RegIdx.Index);
381 }
382
383 /// Coerce the register to FGRH32 and return the real register for the current
384 /// target.
385 unsigned getFGRH32Reg() const {
386 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
387 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
388 .getRegister(RegIdx.Index);
389 }
390
391 /// Coerce the register to FCC and return the real register for the current
392 /// target.
393 unsigned getFCCReg() const {
394 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
395 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
396 .getRegister(RegIdx.Index);
397 }
398
399 /// Coerce the register to MSA128 and return the real register for the current
400 /// target.
401 unsigned getMSA128Reg() const {
402 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
403 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
404 // identical
405 unsigned ClassID = Mips::MSA128BRegClassID;
406 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
407 }
408
409 /// Coerce the register to MSACtrl and return the real register for the
410 /// current target.
411 unsigned getMSACtrlReg() const {
412 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
413 unsigned ClassID = Mips::MSACtrlRegClassID;
414 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
415 }
416
417 /// Coerce the register to COP2 and return the real register for the
418 /// current target.
419 unsigned getCOP2Reg() const {
420 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
421 unsigned ClassID = Mips::COP2RegClassID;
422 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
423 }
424
425 /// Coerce the register to ACC64DSP and return the real register for the
426 /// current target.
427 unsigned getACC64DSPReg() const {
428 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
429 unsigned ClassID = Mips::ACC64DSPRegClassID;
430 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
431 }
432
433 /// Coerce the register to HI32DSP and return the real register for the
434 /// current target.
435 unsigned getHI32DSPReg() const {
436 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
437 unsigned ClassID = Mips::HI32DSPRegClassID;
438 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
439 }
440
441 /// Coerce the register to LO32DSP and return the real register for the
442 /// current target.
443 unsigned getLO32DSPReg() const {
444 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
445 unsigned ClassID = Mips::LO32DSPRegClassID;
446 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
447 }
448
449 /// Coerce the register to CCR and return the real register for the
450 /// current target.
451 unsigned getCCRReg() const {
452 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
453 unsigned ClassID = Mips::CCRRegClassID;
454 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
455 }
456
457 /// Coerce the register to HWRegs and return the real register for the
458 /// current target.
459 unsigned getHWRegsReg() const {
460 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
461 unsigned ClassID = Mips::HWRegsRegClassID;
462 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
463 }
464
465public:
Vladimir Medic4c299852013-11-06 11:27:05 +0000466 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000467 // Add as immediate when possible. Null MCExpr = 0.
468 if (Expr == 0)
469 Inst.addOperand(MCOperand::CreateImm(0));
470 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
471 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
472 else
473 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000474 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000475
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000476 void addRegOperands(MCInst &Inst, unsigned N) const {
477 llvm_unreachable("Use a custom parser instead");
478 }
479
Daniel Sanders21bce302014-04-01 12:35:23 +0000480 /// Render the operand to an MCInst as a GPR32
481 /// Asserts if the wrong number of operands are requested, or the operand
482 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000483 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
484 assert(N == 1 && "Invalid number of operands!");
485 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
486 }
487
Daniel Sanders21bce302014-04-01 12:35:23 +0000488 /// Render the operand to an MCInst as a GPR64
489 /// Asserts if the wrong number of operands are requested, or the operand
490 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000491 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
492 assert(N == 1 && "Invalid number of operands!");
493 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
494 }
495
496 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
497 assert(N == 1 && "Invalid number of operands!");
498 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
499 }
500
501 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
502 assert(N == 1 && "Invalid number of operands!");
503 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
504 }
505
506 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
507 assert(N == 1 && "Invalid number of operands!");
508 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
509 }
510
511 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
512 assert(N == 1 && "Invalid number of operands!");
513 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
514 }
515
516 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
517 assert(N == 1 && "Invalid number of operands!");
518 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
519 }
520
521 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
522 assert(N == 1 && "Invalid number of operands!");
523 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
524 }
525
526 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
527 assert(N == 1 && "Invalid number of operands!");
528 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
529 }
530
531 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
532 assert(N == 1 && "Invalid number of operands!");
533 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
534 }
535
536 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
537 assert(N == 1 && "Invalid number of operands!");
538 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
539 }
540
541 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
542 assert(N == 1 && "Invalid number of operands!");
543 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
544 }
545
546 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
547 assert(N == 1 && "Invalid number of operands!");
548 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
549 }
550
551 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
552 assert(N == 1 && "Invalid number of operands!");
553 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
554 }
555
556 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
557 assert(N == 1 && "Invalid number of operands!");
558 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
559 }
560
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000561 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000562 assert(N == 1 && "Invalid number of operands!");
563 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000564 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000565 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000566
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000567 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000568 assert(N == 2 && "Invalid number of operands!");
569
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000570 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
Jack Carterdc1e35d2012-09-06 20:00:02 +0000571
572 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000573 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000574 }
575
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000576 bool isReg() const {
577 // As a special case until we sort out the definition of div/divu, pretend
578 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
579 if (isGPRAsmReg() && RegIdx.Index == 0)
580 return true;
581
582 return Kind == k_PhysRegister;
583 }
584 bool isRegIdx() const { return Kind == k_RegisterIndex; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000585 bool isImm() const { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000586 bool isConstantImm() const {
587 return isImm() && dyn_cast<MCConstantExpr>(getImm());
588 }
589 bool isToken() const {
590 // Note: It's not possible to pretend that other operand kinds are tokens.
591 // The matcher emitter checks tokens first.
592 return Kind == k_Token;
593 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000594 bool isMem() const { return Kind == k_Memory; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000595 bool isInvNum() const { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000596 bool isLSAImm() const {
597 if (!isConstantImm())
598 return false;
599 int64_t Val = getConstantImm();
600 return 1 <= Val && Val <= 4;
601 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000602
603 StringRef getToken() const {
604 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000605 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000606 }
607
608 unsigned getReg() const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000609 // As a special case until we sort out the definition of div/divu, pretend
610 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
611 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
612 RegIdx.Kind & RegKind_GPR)
613 return getGPR32Reg(); // FIXME: GPR64 too
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000614
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000615 assert(Kind == k_PhysRegister && "Invalid access!");
616 return PhysReg.Num;
Jack Carter873c7242013-01-12 01:03:14 +0000617 }
618
Jack Carterb4dbc172012-09-05 23:34:03 +0000619 const MCExpr *getImm() const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000620 assert((Kind == k_Immediate) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000621 return Imm.Val;
622 }
623
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000624 int64_t getConstantImm() const {
625 const MCExpr *Val = getImm();
626 return static_cast<const MCConstantExpr *>(Val)->getValue();
627 }
628
629 MipsOperand *getMemBase() const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000630 assert((Kind == k_Memory) && "Invalid access!");
631 return Mem.Base;
632 }
633
634 const MCExpr *getMemOff() const {
635 assert((Kind == k_Memory) && "Invalid access!");
636 return Mem.Off;
637 }
638
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000639 static MipsOperand *CreateToken(StringRef Str, SMLoc S,
640 MipsAsmParser &Parser) {
641 MipsOperand *Op = new MipsOperand(k_Token, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000642 Op->Tok.Data = Str.data();
643 Op->Tok.Length = Str.size();
644 Op->StartLoc = S;
645 Op->EndLoc = S;
646 return Op;
647 }
648
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000649 /// Create a numeric register (e.g. $1). The exact register remains
650 /// unresolved until an instruction successfully matches
651 static MipsOperand *CreateNumericReg(unsigned Index,
652 const MCRegisterInfo *RegInfo, SMLoc S,
653 SMLoc E, MipsAsmParser &Parser) {
654 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
655 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000656 }
657
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000658 /// Create a register that is definitely a GPR.
659 /// This is typically only used for named registers such as $gp.
660 static MipsOperand *CreateGPRReg(unsigned Index,
661 const MCRegisterInfo *RegInfo, SMLoc S,
662 SMLoc E, MipsAsmParser &Parser) {
663 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000664 }
665
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000666 /// Create a register that is definitely a FGR.
667 /// This is typically only used for named registers such as $f0.
668 static MipsOperand *CreateFGRReg(unsigned Index,
669 const MCRegisterInfo *RegInfo, SMLoc S,
670 SMLoc E, MipsAsmParser &Parser) {
671 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
672 }
673
674 /// Create a register that is definitely an FCC.
675 /// This is typically only used for named registers such as $fcc0.
676 static MipsOperand *CreateFCCReg(unsigned Index,
677 const MCRegisterInfo *RegInfo, SMLoc S,
678 SMLoc E, MipsAsmParser &Parser) {
679 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
680 }
681
682 /// Create a register that is definitely an ACC.
683 /// This is typically only used for named registers such as $ac0.
684 static MipsOperand *CreateACCReg(unsigned Index,
685 const MCRegisterInfo *RegInfo, SMLoc S,
686 SMLoc E, MipsAsmParser &Parser) {
687 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
688 }
689
690 /// Create a register that is definitely an MSA128.
691 /// This is typically only used for named registers such as $w0.
692 static MipsOperand *CreateMSA128Reg(unsigned Index,
693 const MCRegisterInfo *RegInfo, SMLoc S,
694 SMLoc E, MipsAsmParser &Parser) {
695 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
696 }
697
698 /// Create a register that is definitely an MSACtrl.
699 /// This is typically only used for named registers such as $msaaccess.
700 static MipsOperand *CreateMSACtrlReg(unsigned Index,
701 const MCRegisterInfo *RegInfo, SMLoc S,
702 SMLoc E, MipsAsmParser &Parser) {
703 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
704 }
705
706 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
707 MipsAsmParser &Parser) {
708 MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000709 Op->Imm.Val = Val;
710 Op->StartLoc = S;
711 Op->EndLoc = E;
712 return Op;
713 }
714
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000715 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
716 SMLoc E, MipsAsmParser &Parser) {
717 MipsOperand *Op = new MipsOperand(k_Memory, Parser);
Jack Carterdc1e35d2012-09-06 20:00:02 +0000718 Op->Mem.Base = Base;
719 Op->Mem.Off = Off;
720 Op->StartLoc = S;
721 Op->EndLoc = E;
722 return Op;
723 }
724
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000725 bool isGPRAsmReg() const {
726 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000727 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000728 bool isFGRAsmReg() const {
729 // AFGR64 is $0-$15 but we handle this in getAFGR64()
730 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000731 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000732 bool isHWRegsAsmReg() const {
733 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000734 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000735 bool isCCRAsmReg() const {
736 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000737 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000738 bool isFCCAsmReg() const {
739 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
Jack Carter873c7242013-01-12 01:03:14 +0000740 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000741 bool isACCAsmReg() const {
742 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
Vladimir Medic233dd512013-06-24 10:05:34 +0000743 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000744 bool isCOP2AsmReg() const {
745 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000746 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000747 bool isMSA128AsmReg() const {
748 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000749 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000750 bool isMSACtrlAsmReg() const {
751 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000752 }
753
Jack Carterb4dbc172012-09-05 23:34:03 +0000754 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000755 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000756 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000757 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000758
NAKAMURA Takumie1f35832014-04-15 14:13:21 +0000759 virtual ~MipsOperand() {
760 switch (Kind) {
761 case k_Immediate:
762 break;
763 case k_Memory:
764 delete Mem.Base;
765 break;
766 case k_PhysRegister:
767 case k_RegisterIndex:
768 case k_Token:
769 break;
770 }
771 }
772
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000773 virtual void print(raw_ostream &OS) const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000774 switch (Kind) {
775 case k_Immediate:
776 OS << "Imm<";
777 Imm.Val->print(OS);
778 OS << ">";
779 break;
780 case k_Memory:
781 OS << "Mem<";
782 Mem.Base->print(OS);
783 OS << ", ";
784 Mem.Off->print(OS);
785 OS << ">";
786 break;
787 case k_PhysRegister:
788 OS << "PhysReg<" << PhysReg.Num << ">";
789 break;
790 case k_RegisterIndex:
791 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
792 break;
793 case k_Token:
794 OS << Tok.Data;
795 break;
796 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000797 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000798}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000799} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000800
Jack Carter9e65aa32013-03-22 00:05:30 +0000801namespace llvm {
802extern const MCInstrDesc MipsInsts[];
803}
804static const MCInstrDesc &getInstDesc(unsigned Opcode) {
805 return MipsInsts[Opcode];
806}
807
808bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000809 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000810 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000811
Jack Carter9e65aa32013-03-22 00:05:30 +0000812 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000813
814 if (MCID.isBranch() || MCID.isCall()) {
815 const unsigned Opcode = Inst.getOpcode();
816 MCOperand Offset;
817
818 switch (Opcode) {
819 default:
820 break;
821 case Mips::BEQ:
822 case Mips::BNE:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000823 case Mips::BEQ_MM:
824 case Mips::BNE_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000825 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000826 Offset = Inst.getOperand(2);
827 if (!Offset.isImm())
828 break; // We'll deal with this situation later on when applying fixups.
829 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
830 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000831 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000832 return Error(IDLoc, "branch to misaligned address");
833 break;
834 case Mips::BGEZ:
835 case Mips::BGTZ:
836 case Mips::BLEZ:
837 case Mips::BLTZ:
838 case Mips::BGEZAL:
839 case Mips::BLTZAL:
840 case Mips::BC1F:
841 case Mips::BC1T:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000842 case Mips::BGEZ_MM:
843 case Mips::BGTZ_MM:
844 case Mips::BLEZ_MM:
845 case Mips::BLTZ_MM:
846 case Mips::BGEZAL_MM:
847 case Mips::BLTZAL_MM:
848 case Mips::BC1F_MM:
849 case Mips::BC1T_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000850 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000851 Offset = Inst.getOperand(1);
852 if (!Offset.isImm())
853 break; // We'll deal with this situation later on when applying fixups.
854 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
855 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000856 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000857 return Error(IDLoc, "branch to misaligned address");
858 break;
859 }
860 }
861
Jack Carterc15c1d22013-04-25 23:31:35 +0000862 if (MCID.hasDelaySlot() && Options.isReorder()) {
863 // If this instruction has a delay slot and .set reorder is active,
864 // emit a NOP after it.
865 Instructions.push_back(Inst);
866 MCInst NopInst;
867 NopInst.setOpcode(Mips::SLL);
868 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
869 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
870 NopInst.addOperand(MCOperand::CreateImm(0));
871 Instructions.push_back(NopInst);
872 return false;
873 }
874
Jack Carter9e65aa32013-03-22 00:05:30 +0000875 if (MCID.mayLoad() || MCID.mayStore()) {
876 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000877 // reference or immediate we may have to expand instructions.
878 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000879 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000880 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
881 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000882 MCOperand &Op = Inst.getOperand(i);
883 if (Op.isImm()) {
884 int MemOffset = Op.getImm();
885 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000886 // Offset can't exceed 16bit value.
887 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000888 return false;
889 }
890 } else if (Op.isExpr()) {
891 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000892 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000893 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000894 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000895 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000896 // Expand symbol.
897 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000898 return false;
899 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000900 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000901 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000902 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000903 }
904 }
905 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000906 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000907 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000908
909 if (needsExpansion(Inst))
910 expandInstruction(Inst, IDLoc, Instructions);
911 else
912 Instructions.push_back(Inst);
913
914 return false;
915}
916
Jack Carter30a59822012-10-04 04:03:53 +0000917bool MipsAsmParser::needsExpansion(MCInst &Inst) {
918
Jack Carterd0bd6422013-04-18 00:41:53 +0000919 switch (Inst.getOpcode()) {
920 case Mips::LoadImm32Reg:
921 case Mips::LoadAddr32Imm:
922 case Mips::LoadAddr32Reg:
923 return true;
924 default:
925 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000926 }
927}
Jack Carter92995f12012-10-06 00:53:28 +0000928
Jack Carter30a59822012-10-04 04:03:53 +0000929void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000930 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000931 switch (Inst.getOpcode()) {
932 case Mips::LoadImm32Reg:
933 return expandLoadImm(Inst, IDLoc, Instructions);
934 case Mips::LoadAddr32Imm:
935 return expandLoadAddressImm(Inst, IDLoc, Instructions);
936 case Mips::LoadAddr32Reg:
937 return expandLoadAddressReg(Inst, IDLoc, Instructions);
938 }
Jack Carter30a59822012-10-04 04:03:53 +0000939}
Jack Carter92995f12012-10-06 00:53:28 +0000940
Jack Carter30a59822012-10-04 04:03:53 +0000941void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000942 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000943 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000944 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000945 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000946 const MCOperand &RegOp = Inst.getOperand(0);
947 assert(RegOp.isReg() && "expected register operand kind");
948
949 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000950 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000951 if (0 <= ImmValue && ImmValue <= 65535) {
952 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000953 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000954 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000955 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000956 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000957 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000958 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000959 } else if (ImmValue < 0 && ImmValue >= -32768) {
960 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000961 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000962 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000963 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000964 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000965 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000966 Instructions.push_back(tmpInst);
967 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000968 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000969 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000970 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000971 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000972 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
973 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000974 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000975 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000976 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000977 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
978 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
979 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
980 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000981 Instructions.push_back(tmpInst);
982 }
983}
Jack Carter92995f12012-10-06 00:53:28 +0000984
Vladimir Medic4c299852013-11-06 11:27:05 +0000985void
986MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
987 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000988 MCInst tmpInst;
989 const MCOperand &ImmOp = Inst.getOperand(2);
990 assert(ImmOp.isImm() && "expected immediate operand kind");
991 const MCOperand &SrcRegOp = Inst.getOperand(1);
992 assert(SrcRegOp.isReg() && "expected register operand kind");
993 const MCOperand &DstRegOp = Inst.getOperand(0);
994 assert(DstRegOp.isReg() && "expected register operand kind");
995 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000996 if (-32768 <= ImmValue && ImmValue <= 65535) {
997 // For -32768 <= j <= 65535.
998 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +0000999 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +00001000 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1001 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1002 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1003 Instructions.push_back(tmpInst);
1004 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001005 // For any other value of j that is representable as a 32-bit integer.
1006 // la d,j(s) => lui d,hi16(j)
1007 // ori d,d,lo16(j)
1008 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +00001009 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001010 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1011 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1012 Instructions.push_back(tmpInst);
1013 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001014 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001015 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1016 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1017 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1018 Instructions.push_back(tmpInst);
1019 tmpInst.clear();
1020 tmpInst.setOpcode(Mips::ADDu);
1021 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1022 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1023 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1024 Instructions.push_back(tmpInst);
1025 }
1026}
1027
Vladimir Medic4c299852013-11-06 11:27:05 +00001028void
1029MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1030 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +00001031 MCInst tmpInst;
1032 const MCOperand &ImmOp = Inst.getOperand(1);
1033 assert(ImmOp.isImm() && "expected immediate operand kind");
1034 const MCOperand &RegOp = Inst.getOperand(0);
1035 assert(RegOp.isReg() && "expected register operand kind");
1036 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001037 if (-32768 <= ImmValue && ImmValue <= 65535) {
1038 // For -32768 <= j <= 65535.
1039 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +00001040 tmpInst.setOpcode(Mips::ADDiu);
1041 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +00001042 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +00001043 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1044 Instructions.push_back(tmpInst);
1045 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001046 // For any other value of j that is representable as a 32-bit integer.
1047 // la d,j => lui d,hi16(j)
1048 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +00001049 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001050 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1051 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1052 Instructions.push_back(tmpInst);
1053 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001054 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001055 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1056 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1057 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1058 Instructions.push_back(tmpInst);
1059 }
1060}
1061
Jack Carter9e65aa32013-03-22 00:05:30 +00001062void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +00001063 SmallVectorImpl<MCInst> &Instructions,
1064 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +00001065 const MCSymbolRefExpr *SR;
1066 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +00001067 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +00001068 const MCExpr *ExprOffset;
1069 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +00001070 unsigned AtRegNum = getReg(
Daniel Sanders5e94e682014-03-27 16:42:17 +00001071 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +00001072 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001073 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1074 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001075 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001076 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1077 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001078 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +00001079 if (isImmOpnd) {
1080 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1081 ImmOffset = Inst.getOperand(2).getImm();
1082 LoOffset = ImmOffset & 0x0000ffff;
1083 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +00001084 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +00001085 if (LoOffset & 0x8000)
1086 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +00001087 } else
Jack Carter9e65aa32013-03-22 00:05:30 +00001088 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +00001089 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +00001090 TempInst.setLoc(IDLoc);
1091 // 1st instruction in expansion is LUi. For load instruction we can use
1092 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +00001093 // but for stores we must use $at.
1094 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +00001095 TempInst.setOpcode(Mips::LUi);
1096 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1097 if (isImmOpnd)
1098 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1099 else {
1100 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001101 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +00001102 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1103 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1104 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001105 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001106 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001107 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +00001108 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001109 }
1110 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001111 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +00001112 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +00001113 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +00001114 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +00001115 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001116 TempInst.setOpcode(Mips::ADDu);
1117 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1118 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1119 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1120 Instructions.push_back(TempInst);
1121 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +00001122 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +00001123 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001124 TempInst.setOpcode(Inst.getOpcode());
1125 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1126 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1127 if (isImmOpnd)
1128 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1129 else {
1130 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001131 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1132 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1133 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001134 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001135 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001136 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +00001137 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001138 }
1139 }
1140 Instructions.push_back(TempInst);
1141 TempInst.clear();
1142}
1143
Vladimir Medic4c299852013-11-06 11:27:05 +00001144bool MipsAsmParser::MatchAndEmitInstruction(
1145 SMLoc IDLoc, unsigned &Opcode,
1146 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
1147 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001148 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +00001149 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +00001150 unsigned MatchResult =
1151 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +00001152
1153 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001154 default:
1155 break;
Jack Carterb4dbc172012-09-05 23:34:03 +00001156 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001157 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +00001158 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +00001159 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +00001160 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +00001161 return false;
1162 }
1163 case Match_MissingFeature:
1164 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1165 return true;
1166 case Match_InvalidOperand: {
1167 SMLoc ErrorLoc = IDLoc;
1168 if (ErrorInfo != ~0U) {
1169 if (ErrorInfo >= Operands.size())
1170 return Error(IDLoc, "too few operands for instruction");
1171
Vladimir Medic4c299852013-11-06 11:27:05 +00001172 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001173 if (ErrorLoc == SMLoc())
1174 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +00001175 }
1176
1177 return Error(ErrorLoc, "invalid operand for instruction");
1178 }
1179 case Match_MnemonicFail:
1180 return Error(IDLoc, "invalid instruction");
1181 }
Rafael Espindola870c4e92012-01-11 03:56:41 +00001182 return true;
1183}
1184
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001185void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1186 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1187 if (RegIndex == 1)
1188 Warning(Loc, "Used $at without \".set noat\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001189 else
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001190 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1191 Twine(RegIndex) + "\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001192 }
1193}
1194
Jack Carter1ac53222013-02-20 23:11:17 +00001195int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001196 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +00001197
Vladimir Medic4c299852013-11-06 11:27:05 +00001198 CC = StringSwitch<unsigned>(Name)
1199 .Case("zero", 0)
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001200 .Case("at", 1)
Vladimir Medic4c299852013-11-06 11:27:05 +00001201 .Case("a0", 4)
1202 .Case("a1", 5)
1203 .Case("a2", 6)
1204 .Case("a3", 7)
1205 .Case("v0", 2)
1206 .Case("v1", 3)
1207 .Case("s0", 16)
1208 .Case("s1", 17)
1209 .Case("s2", 18)
1210 .Case("s3", 19)
1211 .Case("s4", 20)
1212 .Case("s5", 21)
1213 .Case("s6", 22)
1214 .Case("s7", 23)
1215 .Case("k0", 26)
1216 .Case("k1", 27)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001217 .Case("gp", 28)
Vladimir Medic4c299852013-11-06 11:27:05 +00001218 .Case("sp", 29)
1219 .Case("fp", 30)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001220 .Case("s8", 30)
Vladimir Medic4c299852013-11-06 11:27:05 +00001221 .Case("ra", 31)
1222 .Case("t0", 8)
1223 .Case("t1", 9)
1224 .Case("t2", 10)
1225 .Case("t3", 11)
1226 .Case("t4", 12)
1227 .Case("t5", 13)
1228 .Case("t6", 14)
1229 .Case("t7", 15)
1230 .Case("t8", 24)
1231 .Case("t9", 25)
1232 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001233
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001234 if (isN32() || isN64()) {
1235 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1236 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1237 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1238 if (8 <= CC && CC <= 11)
1239 CC += 4;
Jack Carter1ac53222013-02-20 23:11:17 +00001240
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001241 if (CC == -1)
1242 CC = StringSwitch<unsigned>(Name)
1243 .Case("a4", 8)
1244 .Case("a5", 9)
1245 .Case("a6", 10)
1246 .Case("a7", 11)
1247 .Case("kt0", 26)
1248 .Case("kt1", 27)
1249 .Default(-1);
1250 }
Jack Carter1ac53222013-02-20 23:11:17 +00001251
1252 return CC;
1253}
Jack Carterd0bd6422013-04-18 00:41:53 +00001254
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001255int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001256
Jack Cartera63b16a2012-09-07 00:23:42 +00001257 if (Name[0] == 'f') {
1258 StringRef NumString = Name.substr(1);
1259 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001260 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001261 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001262 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001263 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001264 return IntVal;
1265 }
1266 return -1;
1267}
Jack Cartera63b16a2012-09-07 00:23:42 +00001268
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001269int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1270
1271 if (Name.startswith("fcc")) {
1272 StringRef NumString = Name.substr(3);
1273 unsigned IntVal;
1274 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001275 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001276 if (IntVal > 7) // There are only 8 fcc registers.
1277 return -1;
1278 return IntVal;
1279 }
1280 return -1;
1281}
1282
1283int MipsAsmParser::matchACRegisterName(StringRef Name) {
1284
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001285 if (Name.startswith("ac")) {
1286 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001287 unsigned IntVal;
1288 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001289 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001290 if (IntVal > 3) // There are only 3 acc registers.
1291 return -1;
1292 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001293 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001294 return -1;
1295}
Jack Carterd0bd6422013-04-18 00:41:53 +00001296
Jack Carter5dc8ac92013-09-25 23:50:44 +00001297int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1298 unsigned IntVal;
1299
1300 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1301 return -1;
1302
1303 if (IntVal > 31)
1304 return -1;
1305
1306 return IntVal;
1307}
1308
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001309int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1310 int CC;
1311
1312 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001313 .Case("msair", 0)
1314 .Case("msacsr", 1)
1315 .Case("msaaccess", 2)
1316 .Case("msasave", 3)
1317 .Case("msamodify", 4)
1318 .Case("msarequest", 5)
1319 .Case("msamap", 6)
1320 .Case("msaunmap", 7)
1321 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001322
1323 return CC;
1324}
1325
Jack Carter0b744b32012-10-04 02:29:46 +00001326bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1327 if (Reg > 31)
1328 return false;
1329
1330 aTReg = Reg;
1331 return true;
1332}
1333
Daniel Sandersd89b1362014-03-24 16:48:01 +00001334int MipsAsmParser::getATReg() {
1335 int AT = Options.getATRegNum();
1336 if (AT == 0)
1337 TokError("Pseudo instruction requires $at, which is not available");
1338 return AT;
1339}
Jack Carter0b744b32012-10-04 02:29:46 +00001340
Jack Carterd0bd6422013-04-18 00:41:53 +00001341unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001342 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001343}
1344
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001345unsigned MipsAsmParser::getGPR(int RegNo) {
Daniel Sanders5e94e682014-03-27 16:42:17 +00001346 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1347 RegNo);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001348}
1349
Jack Carter873c7242013-01-12 01:03:14 +00001350int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001351 if (RegNum >
Daniel Sanders64cf5a42014-03-27 15:00:44 +00001352 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
Jack Carterb4dbc172012-09-05 23:34:03 +00001353 return -1;
1354
Jack Carter873c7242013-01-12 01:03:14 +00001355 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001356}
1357
Vladimir Medic4c299852013-11-06 11:27:05 +00001358bool
1359MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1360 StringRef Mnemonic) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001361 DEBUG(dbgs() << "ParseOperand\n");
1362
Jack Carter30a59822012-10-04 04:03:53 +00001363 // Check if the current operand has a custom associated parser, if so, try to
1364 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001365 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1366 if (ResTy == MatchOperand_Success)
1367 return false;
1368 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1369 // there was a match, but an error occurred, in which case, just return that
1370 // the operand parsing failed.
1371 if (ResTy == MatchOperand_ParseFail)
1372 return true;
1373
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001374 DEBUG(dbgs() << ".. Generic Parser\n");
1375
Jack Carterb4dbc172012-09-05 23:34:03 +00001376 switch (getLexer().getKind()) {
1377 default:
1378 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1379 return true;
1380 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001381 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001382 SMLoc S = Parser.getTok().getLoc();
Jack Carterb4dbc172012-09-05 23:34:03 +00001383
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001384 // Almost all registers have been parsed by custom parsers. There is only
1385 // one exception to this. $zero (and it's alias $0) will reach this point
1386 // for div, divu, and similar instructions because it is not an operand
1387 // to the instruction definition but an explicit register. Special case
1388 // this situation for now.
1389 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
Jack Carterb4dbc172012-09-05 23:34:03 +00001390 return false;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001391
Jack Carterd0bd6422013-04-18 00:41:53 +00001392 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001393 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001394 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001395 return true;
1396
Jack Carter873c7242013-01-12 01:03:14 +00001397 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001398 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001399 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001400 const MCExpr *Res =
1401 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001402
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001403 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001404 return false;
1405 }
Vladimir Medic4c299852013-11-06 11:27:05 +00001406 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001407 case AsmToken::LParen:
1408 case AsmToken::Minus:
1409 case AsmToken::Plus:
1410 case AsmToken::Integer:
1411 case AsmToken::String: {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001412 DEBUG(dbgs() << ".. generic integer\n");
1413 OperandMatchResultTy ResTy = ParseImm(Operands);
1414 return ResTy != MatchOperand_Success;
Jack Carterb4dbc172012-09-05 23:34:03 +00001415 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001416 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001417 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001418 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001419 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001420 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001421 return true;
1422
Jack Carter873c7242013-01-12 01:03:14 +00001423 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1424
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001425 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterdc1e35d2012-09-06 20:00:02 +00001426 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001427 } // case AsmToken::Percent
1428 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001429 return true;
1430}
1431
Vladimir Medic4c299852013-11-06 11:27:05 +00001432const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001433 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001434 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001435 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001436 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Sasa Stankovic06c47802014-04-03 10:37:45 +00001437 // It's a constant, evaluate reloc value.
1438 int16_t Val;
1439 switch (getVariantKind(RelocStr)) {
1440 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1441 // Get the 1st 16-bits.
1442 Val = MCE->getValue() & 0xffff;
1443 break;
1444 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1445 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1446 // 16 bits being negative.
1447 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1448 break;
1449 case MCSymbolRefExpr::VK_Mips_HIGHER:
1450 // Get the 3rd 16-bits.
1451 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1452 break;
1453 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1454 // Get the 4th 16-bits.
1455 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1456 break;
1457 default:
1458 report_fatal_error("Unsupported reloc value!");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001459 }
Sasa Stankovic06c47802014-04-03 10:37:45 +00001460 return MCConstantExpr::Create(Val, getContext());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001461 }
1462
Jack Carterb5cf5902013-04-17 00:18:04 +00001463 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001464 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001465 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001466 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001467 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001468 return Res;
1469 }
1470
1471 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001472 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1473
Sasa Stankovic06c47802014-04-03 10:37:45 +00001474 // Try to create target expression.
1475 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1476 return MipsMCExpr::Create(VK, Expr, getContext());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001477
Jack Carterd0bd6422013-04-18 00:41:53 +00001478 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1479 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001480 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1481 return Res;
1482 }
1483
1484 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001485 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1486 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1487 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001488 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001489 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001490 return Expr;
1491}
1492
1493bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1494
1495 switch (Expr->getKind()) {
1496 case MCExpr::Constant:
1497 return true;
1498 case MCExpr::SymbolRef:
1499 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1500 case MCExpr::Binary:
1501 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1502 if (!isEvaluated(BE->getLHS()))
1503 return false;
1504 return isEvaluated(BE->getRHS());
1505 }
1506 case MCExpr::Unary:
1507 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001508 case MCExpr::Target:
1509 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001510 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001511 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001512}
Jack Carterd0bd6422013-04-18 00:41:53 +00001513
Jack Carterb5cf5902013-04-17 00:18:04 +00001514bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001515 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001516 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001517 if (Tok.isNot(AsmToken::Identifier))
1518 return true;
1519
1520 std::string Str = Tok.getIdentifier().str();
1521
Jack Carterd0bd6422013-04-18 00:41:53 +00001522 Parser.Lex(); // Eat the identifier.
1523 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001524 const MCExpr *IdVal;
1525 SMLoc EndLoc;
1526
1527 if (getLexer().getKind() == AsmToken::LParen) {
1528 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001529 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001530 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001531 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001532 const AsmToken &nextTok = Parser.getTok();
1533 if (nextTok.isNot(AsmToken::Identifier))
1534 return true;
1535 Str += "(%";
1536 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001537 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001538 if (getLexer().getKind() != AsmToken::LParen)
1539 return true;
1540 } else
1541 break;
1542 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001543 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001544 return true;
1545
1546 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001547 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001548
1549 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001550 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001551
Jack Carterd0bd6422013-04-18 00:41:53 +00001552 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001553 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001554}
1555
Jack Carterb4dbc172012-09-05 23:34:03 +00001556bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1557 SMLoc &EndLoc) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001558 SmallVector<MCParsedAsmOperand *, 1> Operands;
1559 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1560 if (ResTy == MatchOperand_Success) {
1561 assert(Operands.size() == 1);
1562 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
1563 StartLoc = Operand.getStartLoc();
1564 EndLoc = Operand.getEndLoc();
1565
1566 // AFAIK, we only support numeric registers and named GPR's in CFI
1567 // directives.
1568 // Don't worry about eating tokens before failing. Using an unrecognised
1569 // register is a parse error.
1570 if (Operand.isGPRAsmReg()) {
1571 // Resolve to GPR32 or GPR64 appropriately.
1572 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1573 }
1574
NAKAMURA Takumibd524ef2014-04-15 14:06:27 +00001575 delete &Operand;
1576
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001577 return (RegNo == (unsigned)-1);
1578 }
1579
1580 assert(Operands.size() == 0);
Vladimir Medic4c299852013-11-06 11:27:05 +00001581 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001582}
1583
Jack Carterb5cf5902013-04-17 00:18:04 +00001584bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001585 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001586 bool Result = true;
1587
1588 while (getLexer().getKind() == AsmToken::LParen)
1589 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001590
Jack Carterd0bd6422013-04-18 00:41:53 +00001591 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001592 default:
1593 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001594 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001595 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001596 case AsmToken::Integer:
1597 case AsmToken::Minus:
1598 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001599 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001600 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001601 else
1602 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001603 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001604 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001605 break;
Jack Carter873c7242013-01-12 01:03:14 +00001606 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001607 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001608 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001609 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001610}
1611
Jack Carterb4dbc172012-09-05 23:34:03 +00001612MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001613 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001614 DEBUG(dbgs() << "parseMemOperand\n");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001615 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001616 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001617 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001618 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001619 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001620 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001621
Jack Carterb5cf5902013-04-17 00:18:04 +00001622 if (getLexer().getKind() == AsmToken::LParen) {
1623 Parser.Lex();
1624 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001625 }
1626
Jack Carterb5cf5902013-04-17 00:18:04 +00001627 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001628 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001629 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001630
Jack Carterd0bd6422013-04-18 00:41:53 +00001631 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001632 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001633 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001634 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001635 SMLoc E =
1636 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001637 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001638 return MatchOperand_Success;
1639 }
1640 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001641 SMLoc E =
1642 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001643
Jack Carterd0bd6422013-04-18 00:41:53 +00001644 // Zero register assumed, add a memory operand with ZERO as its base.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001645 // "Base" will be managed by k_Memory.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001646 MipsOperand *Base = MipsOperand::CreateGPRReg(
1647 0, getContext().getRegisterInfo(), S, E, *this);
1648 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001649 return MatchOperand_Success;
1650 }
1651 Error(Parser.getTok().getLoc(), "'(' expected");
1652 return MatchOperand_ParseFail;
1653 }
1654
Jack Carterd0bd6422013-04-18 00:41:53 +00001655 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001656 }
1657
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001658 Res = ParseAnyRegister(Operands);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001659 if (Res != MatchOperand_Success)
1660 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001661
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001662 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001663 Error(Parser.getTok().getLoc(), "')' expected");
1664 return MatchOperand_ParseFail;
1665 }
1666
Jack Carter873c7242013-01-12 01:03:14 +00001667 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1668
Jack Carterd0bd6422013-04-18 00:41:53 +00001669 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001670
1671 if (IdVal == 0)
1672 IdVal = MCConstantExpr::Create(0, getContext());
1673
Jack Carterd0bd6422013-04-18 00:41:53 +00001674 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001675 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterd0bd6422013-04-18 00:41:53 +00001676 // Remove the register from the operands.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001677 // "op" will be managed by k_Memory.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001678 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001679 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001680 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1681 int64_t Imm;
1682 if (IdVal->EvaluateAsAbsolute(Imm))
1683 IdVal = MCConstantExpr::Create(Imm, getContext());
1684 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1685 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1686 getContext());
1687 }
1688
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001689 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001690 return MatchOperand_Success;
1691}
1692
Daniel Sanderse34a1202014-03-31 18:51:43 +00001693bool MipsAsmParser::searchSymbolAlias(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001694 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001695
Jack Carterd76b2372013-03-21 21:44:16 +00001696 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1697 if (Sym) {
1698 SMLoc S = Parser.getTok().getLoc();
1699 const MCExpr *Expr;
1700 if (Sym->isVariable())
1701 Expr = Sym->getVariableValue();
1702 else
1703 return false;
1704 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001705 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00001706 const StringRef DefSymbol = Ref->getSymbol().getName();
1707 if (DefSymbol.startswith("$")) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001708 OperandMatchResultTy ResTy =
1709 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
Daniel Sanders09934572014-04-01 10:37:46 +00001710 if (ResTy == MatchOperand_Success) {
1711 Parser.Lex();
Jack Carterd76b2372013-03-21 21:44:16 +00001712 return true;
Daniel Sanders09934572014-04-01 10:37:46 +00001713 } else if (ResTy == MatchOperand_ParseFail)
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001714 llvm_unreachable("Should never ParseFail");
1715 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001716 }
1717 } else if (Expr->getKind() == MCExpr::Constant) {
1718 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00001719 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1720 MipsOperand *op =
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001721 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
Jack Carterd76b2372013-03-21 21:44:16 +00001722 Operands.push_back(op);
1723 return true;
1724 }
1725 }
1726 return false;
1727}
Jack Carterd0bd6422013-04-18 00:41:53 +00001728
Jack Carter873c7242013-01-12 01:03:14 +00001729MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001730MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
1731 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
1732 SMLoc S) {
1733 int Index = matchCPURegisterName(Identifier);
1734 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001735 Operands.push_back(MipsOperand::CreateGPRReg(
1736 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1737 return MatchOperand_Success;
1738 }
1739
1740 Index = matchFPURegisterName(Identifier);
1741 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001742 Operands.push_back(MipsOperand::CreateFGRReg(
1743 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1744 return MatchOperand_Success;
1745 }
1746
1747 Index = matchFCCRegisterName(Identifier);
1748 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001749 Operands.push_back(MipsOperand::CreateFCCReg(
1750 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1751 return MatchOperand_Success;
1752 }
1753
1754 Index = matchACRegisterName(Identifier);
1755 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001756 Operands.push_back(MipsOperand::CreateACCReg(
1757 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1758 return MatchOperand_Success;
1759 }
1760
1761 Index = matchMSA128RegisterName(Identifier);
1762 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001763 Operands.push_back(MipsOperand::CreateMSA128Reg(
1764 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1765 return MatchOperand_Success;
1766 }
1767
1768 Index = matchMSA128CtrlRegisterName(Identifier);
1769 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001770 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1771 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1772 return MatchOperand_Success;
1773 }
1774
1775 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001776}
1777
1778MipsAsmParser::OperandMatchResultTy
Daniel Sanders21bce302014-04-01 12:35:23 +00001779MipsAsmParser::MatchAnyRegisterWithoutDollar(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001780 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
Daniel Sanders315386c2014-04-01 10:40:14 +00001781 auto Token = Parser.getLexer().peekTok(false);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001782
1783 if (Token.is(AsmToken::Identifier)) {
1784 DEBUG(dbgs() << ".. identifier\n");
1785 StringRef Identifier = Token.getIdentifier();
Daniel Sanders09934572014-04-01 10:37:46 +00001786 OperandMatchResultTy ResTy =
1787 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
Daniel Sanders09934572014-04-01 10:37:46 +00001788 return ResTy;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001789 } else if (Token.is(AsmToken::Integer)) {
1790 DEBUG(dbgs() << ".. integer\n");
1791 Operands.push_back(MipsOperand::CreateNumericReg(
1792 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
1793 *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001794 return MatchOperand_Success;
1795 }
1796
1797 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
1798
1799 return MatchOperand_NoMatch;
1800}
1801
1802MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
1803 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1804 DEBUG(dbgs() << "ParseAnyRegister\n");
1805
1806 auto Token = Parser.getTok();
1807
1808 SMLoc S = Token.getLoc();
1809
1810 if (Token.isNot(AsmToken::Dollar)) {
1811 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
1812 if (Token.is(AsmToken::Identifier)) {
1813 if (searchSymbolAlias(Operands))
1814 return MatchOperand_Success;
1815 }
1816 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
1817 return MatchOperand_NoMatch;
1818 }
1819 DEBUG(dbgs() << ".. $\n");
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001820
Daniel Sanders21bce302014-04-01 12:35:23 +00001821 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
Daniel Sanders315386c2014-04-01 10:40:14 +00001822 if (ResTy == MatchOperand_Success) {
1823 Parser.Lex(); // $
1824 Parser.Lex(); // identifier
1825 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001826 return ResTy;
1827}
1828
1829MipsAsmParser::OperandMatchResultTy
1830MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1831 switch (getLexer().getKind()) {
1832 default:
1833 return MatchOperand_NoMatch;
1834 case AsmToken::LParen:
1835 case AsmToken::Minus:
1836 case AsmToken::Plus:
1837 case AsmToken::Integer:
1838 case AsmToken::String:
1839 break;
1840 }
1841
1842 const MCExpr *IdVal;
1843 SMLoc S = Parser.getTok().getLoc();
1844 if (getParser().parseExpression(IdVal))
1845 return MatchOperand_ParseFail;
1846
1847 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1848 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1849 return MatchOperand_Success;
1850}
1851
1852MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
1853 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1854 DEBUG(dbgs() << "ParseJumpTarget\n");
1855
1856 SMLoc S = getLexer().getLoc();
1857
1858 // Integers and expressions are acceptable
1859 OperandMatchResultTy ResTy = ParseImm(Operands);
1860 if (ResTy != MatchOperand_NoMatch)
1861 return ResTy;
1862
Daniel Sanders315386c2014-04-01 10:40:14 +00001863 // Registers are a valid target and have priority over symbols.
1864 ResTy = ParseAnyRegister(Operands);
1865 if (ResTy != MatchOperand_NoMatch)
1866 return ResTy;
1867
Daniel Sandersffd84362014-04-01 10:41:48 +00001868 const MCExpr *Expr = nullptr;
1869 if (Parser.parseExpression(Expr)) {
1870 // We have no way of knowing if a symbol was consumed so we must ParseFail
1871 return MatchOperand_ParseFail;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001872 }
Daniel Sandersffd84362014-04-01 10:41:48 +00001873 Operands.push_back(
1874 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001875 return MatchOperand_Success;
Jack Carter873c7242013-01-12 01:03:14 +00001876}
1877
Vladimir Medic2b953d02013-10-01 09:48:56 +00001878MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001879MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00001880 const MCExpr *IdVal;
1881 // If the first token is '$' we may have register operand.
1882 if (Parser.getTok().is(AsmToken::Dollar))
1883 return MatchOperand_NoMatch;
1884 SMLoc S = Parser.getTok().getLoc();
1885 if (getParser().parseExpression(IdVal))
1886 return MatchOperand_ParseFail;
1887 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00001888 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00001889 int64_t Val = MCE->getValue();
1890 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1891 Operands.push_back(MipsOperand::CreateImm(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001892 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
Vladimir Medic2b953d02013-10-01 09:48:56 +00001893 return MatchOperand_Success;
1894}
1895
Matheus Almeida779c5932013-11-18 12:32:49 +00001896MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001897MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Matheus Almeida779c5932013-11-18 12:32:49 +00001898 switch (getLexer().getKind()) {
1899 default:
1900 return MatchOperand_NoMatch;
1901 case AsmToken::LParen:
1902 case AsmToken::Plus:
1903 case AsmToken::Minus:
1904 case AsmToken::Integer:
1905 break;
1906 }
1907
1908 const MCExpr *Expr;
1909 SMLoc S = Parser.getTok().getLoc();
1910
1911 if (getParser().parseExpression(Expr))
1912 return MatchOperand_ParseFail;
1913
1914 int64_t Val;
1915 if (!Expr->EvaluateAsAbsolute(Val)) {
1916 Error(S, "expected immediate value");
1917 return MatchOperand_ParseFail;
1918 }
1919
1920 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
1921 // and because the CPU always adds one to the immediate field, the allowed
1922 // range becomes 1..4. We'll only check the range here and will deal
1923 // with the addition/subtraction when actually decoding/encoding
1924 // the instruction.
1925 if (Val < 1 || Val > 4) {
1926 Error(S, "immediate not in range (1..4)");
1927 return MatchOperand_ParseFail;
1928 }
1929
Jack Carter3b2c96e2014-01-22 23:31:38 +00001930 Operands.push_back(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001931 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
Matheus Almeida779c5932013-11-18 12:32:49 +00001932 return MatchOperand_Success;
1933}
1934
Jack Carterdc1e35d2012-09-06 20:00:02 +00001935MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1936
Vladimir Medic4c299852013-11-06 11:27:05 +00001937 MCSymbolRefExpr::VariantKind VK =
1938 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1939 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1940 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1941 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1942 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1943 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1944 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1945 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1946 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1947 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1948 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1949 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1950 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1951 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1952 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1953 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1954 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1955 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
Daniel Sandersa567da52014-03-31 15:15:02 +00001956 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
1957 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
1958 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
1959 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
1960 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
1961 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
Vladimir Medic4c299852013-11-06 11:27:05 +00001962 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001963
Daniel Sandersa567da52014-03-31 15:15:02 +00001964 assert (VK != MCSymbolRefExpr::VK_None);
1965
Jack Carterdc1e35d2012-09-06 20:00:02 +00001966 return VK;
1967}
Jack Cartera63b16a2012-09-07 00:23:42 +00001968
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001969/// Sometimes (i.e. load/stores) the operand may be followed immediately by
1970/// either this.
1971/// ::= '(', register, ')'
1972/// handle it before we iterate so we don't get tripped up by the lack of
1973/// a comma.
1974bool MipsAsmParser::ParseParenSuffix(
1975 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1976 if (getLexer().is(AsmToken::LParen)) {
1977 Operands.push_back(
1978 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
1979 Parser.Lex();
1980 if (ParseOperand(Operands, Name)) {
1981 SMLoc Loc = getLexer().getLoc();
1982 Parser.eatToEndOfStatement();
1983 return Error(Loc, "unexpected token in argument list");
1984 }
1985 if (Parser.getTok().isNot(AsmToken::RParen)) {
1986 SMLoc Loc = getLexer().getLoc();
1987 Parser.eatToEndOfStatement();
1988 return Error(Loc, "unexpected token, expected ')'");
1989 }
1990 Operands.push_back(
1991 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
1992 Parser.Lex();
1993 }
1994 return false;
1995}
1996
1997/// Sometimes (i.e. in MSA) the operand may be followed immediately by
1998/// either one of these.
1999/// ::= '[', register, ']'
2000/// ::= '[', integer, ']'
2001/// handle it before we iterate so we don't get tripped up by the lack of
2002/// a comma.
2003bool MipsAsmParser::ParseBracketSuffix(
2004 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2005 if (getLexer().is(AsmToken::LBrac)) {
2006 Operands.push_back(
2007 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2008 Parser.Lex();
2009 if (ParseOperand(Operands, Name)) {
2010 SMLoc Loc = getLexer().getLoc();
2011 Parser.eatToEndOfStatement();
2012 return Error(Loc, "unexpected token in argument list");
2013 }
2014 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2015 SMLoc Loc = getLexer().getLoc();
2016 Parser.eatToEndOfStatement();
2017 return Error(Loc, "unexpected token, expected ']'");
2018 }
2019 Operands.push_back(
2020 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2021 Parser.Lex();
2022 }
2023 return false;
2024}
2025
Vladimir Medic4c299852013-11-06 11:27:05 +00002026bool MipsAsmParser::ParseInstruction(
2027 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2028 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002029 DEBUG(dbgs() << "ParseInstruction\n");
Vladimir Medic74593e62013-07-17 15:00:42 +00002030 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002031 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002032 Parser.eatToEndOfStatement();
2033 return Error(NameLoc, "Unknown instruction");
2034 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002035 // First operand in MCInst is instruction mnemonic.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002036 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00002037
2038 // Read the remaining operands.
2039 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2040 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002041 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002042 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002043 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002044 return Error(Loc, "unexpected token in argument list");
2045 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002046 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2047 return true;
2048 // AFAIK, parenthesis suffixes are never on the first operand
Jack Carterb4dbc172012-09-05 23:34:03 +00002049
Jack Carterd0bd6422013-04-18 00:41:53 +00002050 while (getLexer().is(AsmToken::Comma)) {
2051 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002052 // Parse and remember the operand.
2053 if (ParseOperand(Operands, Name)) {
2054 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002055 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002056 return Error(Loc, "unexpected token in argument list");
2057 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002058 // Parse bracket and parenthesis suffixes before we iterate
2059 if (getLexer().is(AsmToken::LBrac)) {
2060 if (ParseBracketSuffix(Name, Operands))
2061 return true;
2062 } else if (getLexer().is(AsmToken::LParen) &&
2063 ParseParenSuffix(Name, Operands))
2064 return true;
Jack Carterb4dbc172012-09-05 23:34:03 +00002065 }
2066 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002067 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2068 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002069 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002070 return Error(Loc, "unexpected token in argument list");
2071 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002072 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002073 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002074}
2075
Jack Carter0b744b32012-10-04 02:29:46 +00002076bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002077 SMLoc Loc = getLexer().getLoc();
2078 Parser.eatToEndOfStatement();
2079 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002080}
2081
2082bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002083 // Line should look like: ".set noat".
2084 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002085 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002086 // eat noat
2087 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002088 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002089 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2090 reportParseError("unexpected token in statement");
2091 return false;
2092 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002093 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002094 return false;
2095}
Jack Carterd0bd6422013-04-18 00:41:53 +00002096
Jack Carter0b744b32012-10-04 02:29:46 +00002097bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002098 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002099 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002100 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002101 getParser().Lex();
2102 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002103 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002104 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002105 return false;
2106 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002107 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002108 if (getLexer().isNot(AsmToken::Dollar)) {
2109 reportParseError("unexpected token in statement");
2110 return false;
2111 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002112 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002113 const AsmToken &Reg = Parser.getTok();
2114 if (Reg.is(AsmToken::Identifier)) {
2115 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2116 } else if (Reg.is(AsmToken::Integer)) {
2117 AtRegNo = Reg.getIntVal();
2118 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002119 reportParseError("unexpected token in statement");
2120 return false;
2121 }
Jack Carter1ac53222013-02-20 23:11:17 +00002122
Daniel Sanders71a89d922014-03-25 13:01:06 +00002123 if (AtRegNo < 0 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002124 reportParseError("unexpected token in statement");
2125 return false;
2126 }
2127
2128 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002129 reportParseError("unexpected token in statement");
2130 return false;
2131 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002132 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002133
2134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2135 reportParseError("unexpected token in statement");
2136 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002137 }
2138 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002139 return false;
2140 } else {
2141 reportParseError("unexpected token in statement");
2142 return false;
2143 }
2144}
2145
2146bool MipsAsmParser::parseSetReorderDirective() {
2147 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002148 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002149 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2150 reportParseError("unexpected token in statement");
2151 return false;
2152 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002153 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002154 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002155 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002156 return false;
2157}
2158
2159bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002160 Parser.Lex();
2161 // If this is not the end of the statement, report an error.
2162 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2163 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002164 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002165 }
2166 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002167 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002168 Parser.Lex(); // Consume the EndOfStatement.
2169 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002170}
2171
2172bool MipsAsmParser::parseSetMacroDirective() {
2173 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002174 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002175 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2176 reportParseError("unexpected token in statement");
2177 return false;
2178 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002179 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002180 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002181 return false;
2182}
2183
2184bool MipsAsmParser::parseSetNoMacroDirective() {
2185 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002186 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002187 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2188 reportParseError("`noreorder' must be set before `nomacro'");
2189 return false;
2190 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002191 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002192 reportParseError("`noreorder' must be set before `nomacro'");
2193 return false;
2194 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002195 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002196 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002197 return false;
2198}
Jack Carterd76b2372013-03-21 21:44:16 +00002199
Jack Carter39536722014-01-22 23:08:42 +00002200bool MipsAsmParser::parseSetNoMips16Directive() {
2201 Parser.Lex();
2202 // If this is not the end of the statement, report an error.
2203 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2204 reportParseError("unexpected token in statement");
2205 return false;
2206 }
2207 // For now do nothing.
2208 Parser.Lex(); // Consume the EndOfStatement.
2209 return false;
2210}
2211
Jack Carterd76b2372013-03-21 21:44:16 +00002212bool MipsAsmParser::parseSetAssignment() {
2213 StringRef Name;
2214 const MCExpr *Value;
2215
2216 if (Parser.parseIdentifier(Name))
2217 reportParseError("expected identifier after .set");
2218
2219 if (getLexer().isNot(AsmToken::Comma))
2220 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002221 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002222
Jack Carter3b2c96e2014-01-22 23:31:38 +00002223 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002224 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002225
Jack Carterd0bd6422013-04-18 00:41:53 +00002226 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002227 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002228 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002229 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002230 Sym = getContext().GetOrCreateSymbol(Name);
2231 Sym->setVariableValue(Value);
2232
2233 return false;
2234}
Jack Carterd0bd6422013-04-18 00:41:53 +00002235
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002236bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2237 Parser.Lex();
2238 if (getLexer().isNot(AsmToken::EndOfStatement))
2239 return reportParseError("unexpected token in .set directive");
2240
2241 switch(Feature) {
2242 default: llvm_unreachable("Unimplemented feature");
2243 case Mips::FeatureDSP:
2244 setFeatureBits(Mips::FeatureDSP, "dsp");
2245 getTargetStreamer().emitDirectiveSetDsp();
2246 break;
2247 case Mips::FeatureMicroMips:
2248 getTargetStreamer().emitDirectiveSetMicroMips();
2249 break;
2250 case Mips::FeatureMips16:
2251 getTargetStreamer().emitDirectiveSetMips16();
2252 break;
2253 case Mips::FeatureMips32r2:
2254 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2255 getTargetStreamer().emitDirectiveSetMips32R2();
2256 break;
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002257 case Mips::FeatureMips64:
2258 setFeatureBits(Mips::FeatureMips64, "mips64");
2259 getTargetStreamer().emitDirectiveSetMips64();
2260 break;
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002261 case Mips::FeatureMips64r2:
2262 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2263 getTargetStreamer().emitDirectiveSetMips64R2();
2264 break;
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002265 }
2266 return false;
2267}
2268
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002269bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2270 if (!getLexer().is(AsmToken::Dollar))
2271 return false;
2272
2273 Parser.Lex();
2274
2275 const AsmToken &Reg = Parser.getTok();
2276 if (Reg.is(AsmToken::Identifier)) {
2277 RegNum = matchCPURegisterName(Reg.getIdentifier());
2278 } else if (Reg.is(AsmToken::Integer)) {
2279 RegNum = Reg.getIntVal();
2280 } else {
2281 return false;
2282 }
2283
2284 Parser.Lex();
2285 return true;
2286}
2287
2288bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2289 if (getLexer().isNot(AsmToken::Comma)) {
2290 SMLoc Loc = getLexer().getLoc();
2291 Parser.eatToEndOfStatement();
2292 return Error(Loc, ErrorStr);
2293 }
2294
2295 Parser.Lex(); // Eat the comma.
2296 return true;
2297}
2298
2299bool MipsAsmParser::parseDirectiveCPSetup() {
2300 unsigned FuncReg;
2301 unsigned Save;
2302 bool SaveIsReg = true;
2303
2304 if (!parseRegister(FuncReg))
2305 return reportParseError("expected register containing function address");
2306 FuncReg = getGPR(FuncReg);
2307
2308 if (!eatComma("expected comma parsing directive"))
2309 return true;
2310
2311 if (!parseRegister(Save)) {
2312 const AsmToken &Tok = Parser.getTok();
2313 if (Tok.is(AsmToken::Integer)) {
2314 Save = Tok.getIntVal();
2315 SaveIsReg = false;
2316 Parser.Lex();
2317 } else
2318 return reportParseError("expected save register or stack offset");
2319 } else
2320 Save = getGPR(Save);
2321
2322 if (!eatComma("expected comma parsing directive"))
2323 return true;
2324
2325 StringRef Name;
2326 if (Parser.parseIdentifier(Name))
2327 reportParseError("expected identifier");
2328 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2329 unsigned GPReg = getGPR(matchCPURegisterName("gp"));
2330
2331 // FIXME: The code below this point should be in the TargetStreamers.
2332 // Only N32 and N64 emit anything for .cpsetup
2333 // FIXME: We should only emit something for PIC mode too.
2334 if (!isN32() && !isN64())
2335 return false;
2336
2337 MCStreamer &TS = getStreamer();
2338 MCInst Inst;
2339 // Either store the old $gp in a register or on the stack
2340 if (SaveIsReg) {
2341 // move $save, $gpreg
2342 Inst.setOpcode(Mips::DADDu);
2343 Inst.addOperand(MCOperand::CreateReg(Save));
2344 Inst.addOperand(MCOperand::CreateReg(GPReg));
2345 Inst.addOperand(MCOperand::CreateReg(getGPR(0)));
2346 } else {
2347 // sd $gpreg, offset($sp)
2348 Inst.setOpcode(Mips::SD);
2349 Inst.addOperand(MCOperand::CreateReg(GPReg));
2350 Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp"))));
2351 Inst.addOperand(MCOperand::CreateImm(Save));
2352 }
2353 TS.EmitInstruction(Inst, STI);
2354 Inst.clear();
2355
2356 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2357 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI,
2358 getContext());
2359 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2360 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO,
2361 getContext());
2362 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
2363 Inst.setOpcode(Mips::LUi);
2364 Inst.addOperand(MCOperand::CreateReg(GPReg));
2365 Inst.addOperand(MCOperand::CreateExpr(HiExpr));
2366 TS.EmitInstruction(Inst, STI);
2367 Inst.clear();
2368
2369 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
2370 Inst.setOpcode(Mips::ADDiu);
2371 Inst.addOperand(MCOperand::CreateReg(GPReg));
2372 Inst.addOperand(MCOperand::CreateReg(GPReg));
2373 Inst.addOperand(MCOperand::CreateExpr(LoExpr));
2374 TS.EmitInstruction(Inst, STI);
2375 Inst.clear();
2376
2377 // daddu $gp, $gp, $funcreg
2378 Inst.setOpcode(Mips::DADDu);
2379 Inst.addOperand(MCOperand::CreateReg(GPReg));
2380 Inst.addOperand(MCOperand::CreateReg(GPReg));
2381 Inst.addOperand(MCOperand::CreateReg(FuncReg));
2382 TS.EmitInstruction(Inst, STI);
2383 return false;
2384}
2385
Jack Carter0b744b32012-10-04 02:29:46 +00002386bool MipsAsmParser::parseDirectiveSet() {
2387
Jack Carterd0bd6422013-04-18 00:41:53 +00002388 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002389 const AsmToken &Tok = Parser.getTok();
2390
2391 if (Tok.getString() == "noat") {
2392 return parseSetNoAtDirective();
2393 } else if (Tok.getString() == "at") {
2394 return parseSetAtDirective();
2395 } else if (Tok.getString() == "reorder") {
2396 return parseSetReorderDirective();
2397 } else if (Tok.getString() == "noreorder") {
2398 return parseSetNoReorderDirective();
2399 } else if (Tok.getString() == "macro") {
2400 return parseSetMacroDirective();
2401 } else if (Tok.getString() == "nomacro") {
2402 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002403 } else if (Tok.getString() == "mips16") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002404 return parseSetFeature(Mips::FeatureMips16);
Jack Carter0b744b32012-10-04 02:29:46 +00002405 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002406 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002407 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002408 getTargetStreamer().emitDirectiveSetNoMicroMips();
2409 Parser.eatToEndOfStatement();
2410 return false;
2411 } else if (Tok.getString() == "micromips") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002412 return parseSetFeature(Mips::FeatureMicroMips);
Vladimir Medic615b26e2014-03-04 09:54:09 +00002413 } else if (Tok.getString() == "mips32r2") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002414 return parseSetFeature(Mips::FeatureMips32r2);
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002415 } else if (Tok.getString() == "mips64") {
2416 return parseSetFeature(Mips::FeatureMips64);
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002417 } else if (Tok.getString() == "mips64r2") {
2418 return parseSetFeature(Mips::FeatureMips64r2);
Vladimir Medic27c398e2014-03-05 11:05:09 +00002419 } else if (Tok.getString() == "dsp") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002420 return parseSetFeature(Mips::FeatureDSP);
Jack Carterd76b2372013-03-21 21:44:16 +00002421 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002422 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002423 parseSetAssignment();
2424 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002425 }
Jack Carter07c818d2013-01-25 01:31:34 +00002426
Jack Carter0b744b32012-10-04 02:29:46 +00002427 return true;
2428}
2429
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002430/// parseDataDirective
Jack Carter07c818d2013-01-25 01:31:34 +00002431/// ::= .word [ expression (, expression)* ]
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002432bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
Jack Carter07c818d2013-01-25 01:31:34 +00002433 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2434 for (;;) {
2435 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002436 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002437 return true;
2438
2439 getParser().getStreamer().EmitValue(Value, Size);
2440
2441 if (getLexer().is(AsmToken::EndOfStatement))
2442 break;
2443
2444 // FIXME: Improve diagnostic.
2445 if (getLexer().isNot(AsmToken::Comma))
2446 return Error(L, "unexpected token in directive");
2447 Parser.Lex();
2448 }
2449 }
2450
2451 Parser.Lex();
2452 return false;
2453}
2454
Vladimir Medic4c299852013-11-06 11:27:05 +00002455/// parseDirectiveGpWord
2456/// ::= .gpword local_sym
2457bool MipsAsmParser::parseDirectiveGpWord() {
2458 const MCExpr *Value;
2459 // EmitGPRel32Value requires an expression, so we are using base class
2460 // method to evaluate the expression.
2461 if (getParser().parseExpression(Value))
2462 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002463 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002464
Vladimir Medice10c1122013-11-13 13:18:04 +00002465 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002466 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002467 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002468 return false;
2469}
2470
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002471/// parseDirectiveGpDWord
Rafael Espindolab59fb732014-03-28 18:50:26 +00002472/// ::= .gpdword local_sym
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002473bool MipsAsmParser::parseDirectiveGpDWord() {
Rafael Espindolab59fb732014-03-28 18:50:26 +00002474 const MCExpr *Value;
2475 // EmitGPRel64Value requires an expression, so we are using base class
2476 // method to evaluate the expression.
2477 if (getParser().parseExpression(Value))
2478 return true;
2479 getParser().getStreamer().EmitGPRel64Value(Value);
2480
2481 if (getLexer().isNot(AsmToken::EndOfStatement))
2482 return Error(getLexer().getLoc(), "unexpected token in directive");
2483 Parser.Lex(); // Eat EndOfStatement token.
2484 return false;
2485}
2486
Jack Carter0cd3c192014-01-06 23:27:31 +00002487bool MipsAsmParser::parseDirectiveOption() {
2488 // Get the option token.
2489 AsmToken Tok = Parser.getTok();
2490 // At the moment only identifiers are supported.
2491 if (Tok.isNot(AsmToken::Identifier)) {
2492 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2493 Parser.eatToEndOfStatement();
2494 return false;
2495 }
2496
2497 StringRef Option = Tok.getIdentifier();
2498
2499 if (Option == "pic0") {
2500 getTargetStreamer().emitDirectiveOptionPic0();
2501 Parser.Lex();
2502 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2503 Error(Parser.getTok().getLoc(),
2504 "unexpected token in .option pic0 directive");
2505 Parser.eatToEndOfStatement();
2506 }
2507 return false;
2508 }
2509
Matheus Almeidaf79b2812014-03-26 13:40:29 +00002510 if (Option == "pic2") {
2511 getTargetStreamer().emitDirectiveOptionPic2();
2512 Parser.Lex();
2513 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2514 Error(Parser.getTok().getLoc(),
2515 "unexpected token in .option pic2 directive");
2516 Parser.eatToEndOfStatement();
2517 }
2518 return false;
2519 }
2520
Jack Carter0cd3c192014-01-06 23:27:31 +00002521 // Unknown option.
2522 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2523 Parser.eatToEndOfStatement();
2524 return false;
2525}
2526
Jack Carter0b744b32012-10-04 02:29:46 +00002527bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002528 StringRef IDVal = DirectiveID.getString();
2529
Matheus Almeidaab5633b2014-03-26 15:44:18 +00002530 if (IDVal == ".dword") {
2531 parseDataDirective(8, DirectiveID.getLoc());
2532 return false;
2533 }
2534
Jack Carterd0bd6422013-04-18 00:41:53 +00002535 if (IDVal == ".ent") {
2536 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002537 Parser.Lex();
2538 return false;
2539 }
2540
Jack Carter07c818d2013-01-25 01:31:34 +00002541 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002542 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002543 Parser.Lex();
2544 return false;
2545 }
2546
Jack Carter07c818d2013-01-25 01:31:34 +00002547 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002548 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002549 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002550 return false;
2551 }
2552
Jack Carter07c818d2013-01-25 01:31:34 +00002553 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002554 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002555 }
2556
Jack Carter07c818d2013-01-25 01:31:34 +00002557 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002558 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002559 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002560 return false;
2561 }
2562
Jack Carter07c818d2013-01-25 01:31:34 +00002563 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002564 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002565 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002566 return false;
2567 }
2568
Jack Carter07c818d2013-01-25 01:31:34 +00002569 if (IDVal == ".gpword") {
Vladimir Medic4c299852013-11-06 11:27:05 +00002570 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002571 return false;
2572 }
2573
Rafael Espindolab59fb732014-03-28 18:50:26 +00002574 if (IDVal == ".gpdword") {
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002575 parseDirectiveGpDWord();
Rafael Espindolab59fb732014-03-28 18:50:26 +00002576 return false;
2577 }
2578
Jack Carter07c818d2013-01-25 01:31:34 +00002579 if (IDVal == ".word") {
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002580 parseDataDirective(4, DirectiveID.getLoc());
Jack Carter07c818d2013-01-25 01:31:34 +00002581 return false;
2582 }
2583
Jack Carter0cd3c192014-01-06 23:27:31 +00002584 if (IDVal == ".option")
2585 return parseDirectiveOption();
2586
2587 if (IDVal == ".abicalls") {
2588 getTargetStreamer().emitDirectiveAbiCalls();
2589 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2590 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2591 // Clear line
2592 Parser.eatToEndOfStatement();
2593 }
2594 return false;
2595 }
2596
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002597 if (IDVal == ".cpsetup")
2598 return parseDirectiveCPSetup();
2599
Rafael Espindola870c4e92012-01-11 03:56:41 +00002600 return true;
2601}
2602
Rafael Espindola870c4e92012-01-11 03:56:41 +00002603extern "C" void LLVMInitializeMipsAsmParser() {
2604 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2605 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2606 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2607 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2608}
Jack Carterb4dbc172012-09-05 23:34:03 +00002609
2610#define GET_REGISTER_MATCHER
2611#define GET_MATCHER_IMPLEMENTATION
2612#include "MipsGenAsmMatcher.inc"