blob: 4bc681b7a2d00ff8528e0690c9592d8b5b3d55db [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
Chandler Carruthe96dd892014-04-21 22:55:11 +000032#define DEBUG_TYPE "mips-asm-parser"
33
Joey Gouly0e76fa72013-09-12 10:28:05 +000034namespace llvm {
35class MCInstrInfo;
36}
37
Rafael Espindola870c4e92012-01-11 03:56:41 +000038namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000039class MipsAssemblerOptions {
40public:
Vladimir Medic4c299852013-11-06 11:27:05 +000041 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
Jack Carterb4dbc172012-09-05 23:34:03 +000042
Vladimir Medic4c299852013-11-06 11:27:05 +000043 unsigned getATRegNum() { return aTReg; }
Jack Carter0b744b32012-10-04 02:29:46 +000044 bool setATReg(unsigned Reg);
45
Vladimir Medic4c299852013-11-06 11:27:05 +000046 bool isReorder() { return reorder; }
47 void setReorder() { reorder = true; }
48 void setNoreorder() { reorder = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000049
Vladimir Medic4c299852013-11-06 11:27:05 +000050 bool isMacro() { return macro; }
51 void setMacro() { macro = true; }
52 void setNomacro() { macro = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000053
54private:
55 unsigned aTReg;
56 bool reorder;
57 bool macro;
58};
59}
60
61namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000062class MipsAsmParser : public MCTargetAsmParser {
Rafael Espindolaa17151a2013-10-08 13:08:17 +000063 MipsTargetStreamer &getTargetStreamer() {
Rafael Espindola4a1a3602014-01-14 01:21:46 +000064 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
Rafael Espindolaa17151a2013-10-08 13:08:17 +000065 return static_cast<MipsTargetStreamer &>(TS);
66 }
67
Jack Carterb4dbc172012-09-05 23:34:03 +000068 MCSubtargetInfo &STI;
69 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000070 MipsAssemblerOptions Options;
Jack Carter0b744b32012-10-04 02:29:46 +000071
Akira Hatanaka7605630c2012-08-17 20:16:42 +000072#define GET_ASSEMBLER_HEADER
73#include "MipsGenAsmMatcher.inc"
74
Chad Rosier49963552012-10-13 00:26:04 +000075 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Vladimir Medic4c299852013-11-06 11:27:05 +000076 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000077 MCStreamer &Out, unsigned &ErrorInfo,
Craig Topper56c590a2014-04-29 07:58:02 +000078 bool MatchingInlineAsm) override;
Rafael Espindola870c4e92012-01-11 03:56:41 +000079
Daniel Sandersb50ccf82014-04-01 10:35:28 +000080 /// Parse a register as used in CFI directives
Craig Topper56c590a2014-04-29 07:58:02 +000081 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Rafael Espindola870c4e92012-01-11 03:56:41 +000082
Daniel Sandersb50ccf82014-04-01 10:35:28 +000083 bool ParseParenSuffix(StringRef Name,
84 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
85
86 bool ParseBracketSuffix(StringRef Name,
87 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
88
Craig Topper56c590a2014-04-29 07:58:02 +000089 bool
90 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
91 SmallVectorImpl<MCParsedAsmOperand *> &Operands) override;
Rafael Espindola870c4e92012-01-11 03:56:41 +000092
Craig Topper56c590a2014-04-29 07:58:02 +000093 bool ParseDirective(AsmToken DirectiveID) override;
Rafael Espindola870c4e92012-01-11 03:56:41 +000094
Jack Carterb4dbc172012-09-05 23:34:03 +000095 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000096 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000097
Daniel Sandersb50ccf82014-04-01 10:35:28 +000098 MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar(
99 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
100 SMLoc S);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000101
102 MipsAsmParser::OperandMatchResultTy
Daniel Sanders21bce302014-04-01 12:35:23 +0000103 MatchAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000104 SMLoc S);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000105
Jack Carter873c7242013-01-12 01:03:14 +0000106 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000107 ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000108
109 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000110 ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000111
112 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000113 ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000114
115 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000116 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic2b953d02013-10-01 09:48:56 +0000117
Matheus Almeida779c5932013-11-18 12:32:49 +0000118 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000119 ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeida779c5932013-11-18 12:32:49 +0000120
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000121 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carterd76b2372013-03-21 21:44:16 +0000122
Vladimir Medic4c299852013-11-06 11:27:05 +0000123 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
Jack Carterb4dbc172012-09-05 23:34:03 +0000124 StringRef Mnemonic);
125
Jack Carter30a59822012-10-04 04:03:53 +0000126 bool needsExpansion(MCInst &Inst);
127
128 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000129 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000130 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000131 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000132 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
133 SmallVectorImpl<MCInst> &Instructions);
134 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
135 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000136 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000137 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
138 bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000139 bool reportParseError(StringRef ErrorMsg);
140
Jack Carterb5cf5902013-04-17 00:18:04 +0000141 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000142 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000143
Vladimir Medic4c299852013-11-06 11:27:05 +0000144 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000145
146 bool isEvaluated(const MCExpr *Expr);
Matheus Almeidafe1e39d2014-03-26 14:26:27 +0000147 bool parseSetFeature(uint64_t Feature);
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000148 bool parseDirectiveCPSetup();
Matheus Almeida0051f2d2014-04-16 15:48:55 +0000149 bool parseDirectiveNaN();
Jack Carter0b744b32012-10-04 02:29:46 +0000150 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000151 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000152
153 bool parseSetAtDirective();
154 bool parseSetNoAtDirective();
155 bool parseSetMacroDirective();
156 bool parseSetNoMacroDirective();
157 bool parseSetReorderDirective();
158 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000159 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000160
Jack Carterd76b2372013-03-21 21:44:16 +0000161 bool parseSetAssignment();
162
Matheus Almeida3e2a7022014-03-26 15:24:36 +0000163 bool parseDataDirective(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000164 bool parseDirectiveGpWord();
Rafael Espindola2378d4c2014-03-31 14:15:07 +0000165 bool parseDirectiveGpDWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000166
Jack Carterdc1e35d2012-09-06 20:00:02 +0000167 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000168
Daniel Sanders5e94e682014-03-27 16:42:17 +0000169 bool isGP64() const {
170 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
Jack Carterb4dbc172012-09-05 23:34:03 +0000171 }
172
Jack Cartera63b16a2012-09-07 00:23:42 +0000173 bool isFP64() const {
174 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
175 }
176
Daniel Sandersa4b0c742014-03-26 11:39:07 +0000177 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
Vladimir Medic4c299852013-11-06 11:27:05 +0000178 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000179
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000180 bool isMicroMips() const {
181 return STI.getFeatureBits() & Mips::FeatureMicroMips;
182 }
183
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000184 bool parseRegister(unsigned &RegNum);
185
186 bool eatComma(StringRef ErrorStr);
187
Jack Carter1ac53222013-02-20 23:11:17 +0000188 int matchCPURegisterName(StringRef Symbol);
189
Jack Carter873c7242013-01-12 01:03:14 +0000190 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000191
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000192 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000193
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000194 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000195
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000196 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000197
Jack Carter5dc8ac92013-09-25 23:50:44 +0000198 int matchMSA128RegisterName(StringRef Name);
199
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000200 int matchMSA128CtrlRegisterName(StringRef Name);
201
Jack Carterd0bd6422013-04-18 00:41:53 +0000202 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000203
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000204 unsigned getGPR(int RegNo);
205
Jack Carter1ac53222013-02-20 23:11:17 +0000206 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000207
208 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000209 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000210
211 // Helper function that checks if the value of a vector index is within the
212 // boundaries of accepted values for each RegisterKind
213 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
214 bool validateMSAIndex(int Val, int RegKind);
215
Vladimir Medic615b26e2014-03-04 09:54:09 +0000216 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
217 if (!(STI.getFeatureBits() & Feature)) {
Matheus Almeida2852af82014-04-22 10:15:54 +0000218 setAvailableFeatures(
219 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
Vladimir Medic615b26e2014-03-04 09:54:09 +0000220 }
221 }
222
223 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
224 if (STI.getFeatureBits() & Feature) {
Matheus Almeida2852af82014-04-22 10:15:54 +0000225 setAvailableFeatures(
226 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
Vladimir Medic615b26e2014-03-04 09:54:09 +0000227 }
228 }
229
Rafael Espindola870c4e92012-01-11 03:56:41 +0000230public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000231 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
Evgeniy Stepanov0a951b72014-04-23 11:16:03 +0000232 const MCInstrInfo &MII,
233 const MCTargetOptions &Options)
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000234 : MCTargetAsmParser(), STI(sti), Parser(parser) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000235 // Initialize the set of available features.
236 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000237
238 // Assert exactly one ABI was chosen.
239 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
240 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
241 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
242 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000243 }
244
Jack Carterb4dbc172012-09-05 23:34:03 +0000245 MCAsmParser &getParser() const { return Parser; }
246 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000247
248 /// Warn if RegNo is the current assembler temporary.
249 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000250};
251}
252
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000253namespace {
254
255/// MipsOperand - Instances of this class represent a parsed Mips machine
256/// instruction.
257class MipsOperand : public MCParsedAsmOperand {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000258public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000259 /// Broad categories of register classes
260 /// The exact class is finalized by the render method.
261 enum RegKind {
262 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64())
263 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
264 /// isFP64())
265 RegKind_FCC = 4, /// FCC
266 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
267 RegKind_MSACtrl = 16, /// MSA control registers
268 RegKind_COP2 = 32, /// COP2
269 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
270 /// context).
271 RegKind_CCR = 128, /// CCR
272 RegKind_HWRegs = 256, /// HWRegs
273
274 /// Potentially any (e.g. $1)
275 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
276 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
277 RegKind_CCR | RegKind_HWRegs
Jack Carter873c7242013-01-12 01:03:14 +0000278 };
279
280private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000281 enum KindTy {
Daniel Sanders21bce302014-04-01 12:35:23 +0000282 k_Immediate, /// An immediate (possibly involving symbol references)
283 k_Memory, /// Base + Offset Memory Address
284 k_PhysRegister, /// A physical register from the Mips namespace
285 k_RegisterIndex, /// A register index in one or more RegKind.
286 k_Token /// A simple token
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000287 } Kind;
288
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000289 MipsOperand(KindTy K, MipsAsmParser &Parser)
290 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
291
292 /// For diagnostics, and checking the assembler temporary
293 MipsAsmParser &AsmParser;
Jack Carterb4dbc172012-09-05 23:34:03 +0000294
Eric Christopher8996c5d2013-03-15 00:42:55 +0000295 struct Token {
296 const char *Data;
297 unsigned Length;
298 };
299
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000300 struct PhysRegOp {
301 unsigned Num; /// Register Number
302 };
303
304 struct RegIdxOp {
305 unsigned Index; /// Index into the register class
306 RegKind Kind; /// Bitfield of the kinds it could possibly be
307 const MCRegisterInfo *RegInfo;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000308 };
309
310 struct ImmOp {
311 const MCExpr *Val;
312 };
313
314 struct MemOp {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000315 MipsOperand *Base;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000316 const MCExpr *Off;
317 };
318
Jack Carterb4dbc172012-09-05 23:34:03 +0000319 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000320 struct Token Tok;
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000321 struct PhysRegOp PhysReg;
322 struct RegIdxOp RegIdx;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000323 struct ImmOp Imm;
324 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000325 };
326
327 SMLoc StartLoc, EndLoc;
328
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000329 /// Internal constructor for register kinds
330 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
331 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
332 MipsAsmParser &Parser) {
333 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
334 Op->RegIdx.Index = Index;
335 Op->RegIdx.RegInfo = RegInfo;
336 Op->RegIdx.Kind = RegKind;
337 Op->StartLoc = S;
338 Op->EndLoc = E;
339 return Op;
340 }
341
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000342public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000343 /// Coerce the register to GPR32 and return the real register for the current
344 /// target.
345 unsigned getGPR32Reg() const {
346 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
347 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
348 unsigned ClassID = Mips::GPR32RegClassID;
349 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000350 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000351
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000352 /// Coerce the register to GPR64 and return the real register for the current
353 /// target.
354 unsigned getGPR64Reg() const {
355 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
356 unsigned ClassID = Mips::GPR64RegClassID;
357 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000358 }
359
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000360private:
361 /// Coerce the register to AFGR64 and return the real register for the current
362 /// target.
363 unsigned getAFGR64Reg() const {
364 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
365 if (RegIdx.Index % 2 != 0)
366 AsmParser.Warning(StartLoc, "Float register should be even.");
367 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
368 .getRegister(RegIdx.Index / 2);
369 }
370
371 /// Coerce the register to FGR64 and return the real register for the current
372 /// target.
373 unsigned getFGR64Reg() const {
374 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
375 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
376 .getRegister(RegIdx.Index);
377 }
378
379 /// Coerce the register to FGR32 and return the real register for the current
380 /// target.
381 unsigned getFGR32Reg() const {
382 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
383 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
384 .getRegister(RegIdx.Index);
385 }
386
387 /// Coerce the register to FGRH32 and return the real register for the current
388 /// target.
389 unsigned getFGRH32Reg() const {
390 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
391 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
392 .getRegister(RegIdx.Index);
393 }
394
395 /// Coerce the register to FCC and return the real register for the current
396 /// target.
397 unsigned getFCCReg() const {
398 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
399 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
400 .getRegister(RegIdx.Index);
401 }
402
403 /// Coerce the register to MSA128 and return the real register for the current
404 /// target.
405 unsigned getMSA128Reg() const {
406 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
407 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
408 // identical
409 unsigned ClassID = Mips::MSA128BRegClassID;
410 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
411 }
412
413 /// Coerce the register to MSACtrl and return the real register for the
414 /// current target.
415 unsigned getMSACtrlReg() const {
416 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
417 unsigned ClassID = Mips::MSACtrlRegClassID;
418 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
419 }
420
421 /// Coerce the register to COP2 and return the real register for the
422 /// current target.
423 unsigned getCOP2Reg() const {
424 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
425 unsigned ClassID = Mips::COP2RegClassID;
426 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
427 }
428
429 /// Coerce the register to ACC64DSP and return the real register for the
430 /// current target.
431 unsigned getACC64DSPReg() const {
432 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
433 unsigned ClassID = Mips::ACC64DSPRegClassID;
434 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
435 }
436
437 /// Coerce the register to HI32DSP and return the real register for the
438 /// current target.
439 unsigned getHI32DSPReg() const {
440 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
441 unsigned ClassID = Mips::HI32DSPRegClassID;
442 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
443 }
444
445 /// Coerce the register to LO32DSP and return the real register for the
446 /// current target.
447 unsigned getLO32DSPReg() const {
448 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
449 unsigned ClassID = Mips::LO32DSPRegClassID;
450 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
451 }
452
453 /// Coerce the register to CCR and return the real register for the
454 /// current target.
455 unsigned getCCRReg() const {
456 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
457 unsigned ClassID = Mips::CCRRegClassID;
458 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
459 }
460
461 /// Coerce the register to HWRegs and return the real register for the
462 /// current target.
463 unsigned getHWRegsReg() const {
464 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
465 unsigned ClassID = Mips::HWRegsRegClassID;
466 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
467 }
468
469public:
Vladimir Medic4c299852013-11-06 11:27:05 +0000470 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000471 // Add as immediate when possible. Null MCExpr = 0.
Craig Topper062a2ba2014-04-25 05:30:21 +0000472 if (!Expr)
Jack Carterb4dbc172012-09-05 23:34:03 +0000473 Inst.addOperand(MCOperand::CreateImm(0));
474 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
475 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
476 else
477 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000478 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000479
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000480 void addRegOperands(MCInst &Inst, unsigned N) const {
481 llvm_unreachable("Use a custom parser instead");
482 }
483
Daniel Sanders21bce302014-04-01 12:35:23 +0000484 /// Render the operand to an MCInst as a GPR32
485 /// Asserts if the wrong number of operands are requested, or the operand
486 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000487 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
488 assert(N == 1 && "Invalid number of operands!");
489 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
490 }
491
Daniel Sanders21bce302014-04-01 12:35:23 +0000492 /// Render the operand to an MCInst as a GPR64
493 /// Asserts if the wrong number of operands are requested, or the operand
494 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000495 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
496 assert(N == 1 && "Invalid number of operands!");
497 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
498 }
499
500 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
501 assert(N == 1 && "Invalid number of operands!");
502 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
503 }
504
505 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
506 assert(N == 1 && "Invalid number of operands!");
507 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
508 }
509
510 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
511 assert(N == 1 && "Invalid number of operands!");
512 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
513 }
514
515 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
516 assert(N == 1 && "Invalid number of operands!");
517 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
518 }
519
520 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
521 assert(N == 1 && "Invalid number of operands!");
522 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
523 }
524
525 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
526 assert(N == 1 && "Invalid number of operands!");
527 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
528 }
529
530 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
531 assert(N == 1 && "Invalid number of operands!");
532 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
533 }
534
535 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
536 assert(N == 1 && "Invalid number of operands!");
537 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
538 }
539
540 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
541 assert(N == 1 && "Invalid number of operands!");
542 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
543 }
544
545 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
546 assert(N == 1 && "Invalid number of operands!");
547 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
548 }
549
550 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
551 assert(N == 1 && "Invalid number of operands!");
552 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
553 }
554
555 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
556 assert(N == 1 && "Invalid number of operands!");
557 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
558 }
559
560 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
561 assert(N == 1 && "Invalid number of operands!");
562 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
563 }
564
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000565 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000566 assert(N == 1 && "Invalid number of operands!");
567 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000568 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000569 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000570
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000571 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000572 assert(N == 2 && "Invalid number of operands!");
573
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000574 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
Jack Carterdc1e35d2012-09-06 20:00:02 +0000575
576 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000577 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000578 }
579
Craig Topper56c590a2014-04-29 07:58:02 +0000580 bool isReg() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000581 // As a special case until we sort out the definition of div/divu, pretend
582 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
583 if (isGPRAsmReg() && RegIdx.Index == 0)
584 return true;
585
586 return Kind == k_PhysRegister;
587 }
588 bool isRegIdx() const { return Kind == k_RegisterIndex; }
Craig Topper56c590a2014-04-29 07:58:02 +0000589 bool isImm() const override { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000590 bool isConstantImm() const {
591 return isImm() && dyn_cast<MCConstantExpr>(getImm());
592 }
Craig Topper56c590a2014-04-29 07:58:02 +0000593 bool isToken() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000594 // Note: It's not possible to pretend that other operand kinds are tokens.
595 // The matcher emitter checks tokens first.
596 return Kind == k_Token;
597 }
Craig Topper56c590a2014-04-29 07:58:02 +0000598 bool isMem() const override { return Kind == k_Memory; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000599 bool isInvNum() const { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000600 bool isLSAImm() const {
601 if (!isConstantImm())
602 return false;
603 int64_t Val = getConstantImm();
604 return 1 <= Val && Val <= 4;
605 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000606
607 StringRef getToken() const {
608 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000609 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000610 }
611
Craig Topper56c590a2014-04-29 07:58:02 +0000612 unsigned getReg() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000613 // As a special case until we sort out the definition of div/divu, pretend
614 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
615 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
616 RegIdx.Kind & RegKind_GPR)
617 return getGPR32Reg(); // FIXME: GPR64 too
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000618
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000619 assert(Kind == k_PhysRegister && "Invalid access!");
620 return PhysReg.Num;
Jack Carter873c7242013-01-12 01:03:14 +0000621 }
622
Jack Carterb4dbc172012-09-05 23:34:03 +0000623 const MCExpr *getImm() const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000624 assert((Kind == k_Immediate) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000625 return Imm.Val;
626 }
627
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000628 int64_t getConstantImm() const {
629 const MCExpr *Val = getImm();
630 return static_cast<const MCConstantExpr *>(Val)->getValue();
631 }
632
633 MipsOperand *getMemBase() const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000634 assert((Kind == k_Memory) && "Invalid access!");
635 return Mem.Base;
636 }
637
638 const MCExpr *getMemOff() const {
639 assert((Kind == k_Memory) && "Invalid access!");
640 return Mem.Off;
641 }
642
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000643 static MipsOperand *CreateToken(StringRef Str, SMLoc S,
644 MipsAsmParser &Parser) {
645 MipsOperand *Op = new MipsOperand(k_Token, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000646 Op->Tok.Data = Str.data();
647 Op->Tok.Length = Str.size();
648 Op->StartLoc = S;
649 Op->EndLoc = S;
650 return Op;
651 }
652
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000653 /// Create a numeric register (e.g. $1). The exact register remains
654 /// unresolved until an instruction successfully matches
655 static MipsOperand *CreateNumericReg(unsigned Index,
656 const MCRegisterInfo *RegInfo, SMLoc S,
657 SMLoc E, MipsAsmParser &Parser) {
658 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
659 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000660 }
661
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000662 /// Create a register that is definitely a GPR.
663 /// This is typically only used for named registers such as $gp.
664 static MipsOperand *CreateGPRReg(unsigned Index,
665 const MCRegisterInfo *RegInfo, SMLoc S,
666 SMLoc E, MipsAsmParser &Parser) {
667 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000668 }
669
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000670 /// Create a register that is definitely a FGR.
671 /// This is typically only used for named registers such as $f0.
672 static MipsOperand *CreateFGRReg(unsigned Index,
673 const MCRegisterInfo *RegInfo, SMLoc S,
674 SMLoc E, MipsAsmParser &Parser) {
675 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
676 }
677
678 /// Create a register that is definitely an FCC.
679 /// This is typically only used for named registers such as $fcc0.
680 static MipsOperand *CreateFCCReg(unsigned Index,
681 const MCRegisterInfo *RegInfo, SMLoc S,
682 SMLoc E, MipsAsmParser &Parser) {
683 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
684 }
685
686 /// Create a register that is definitely an ACC.
687 /// This is typically only used for named registers such as $ac0.
688 static MipsOperand *CreateACCReg(unsigned Index,
689 const MCRegisterInfo *RegInfo, SMLoc S,
690 SMLoc E, MipsAsmParser &Parser) {
691 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
692 }
693
694 /// Create a register that is definitely an MSA128.
695 /// This is typically only used for named registers such as $w0.
696 static MipsOperand *CreateMSA128Reg(unsigned Index,
697 const MCRegisterInfo *RegInfo, SMLoc S,
698 SMLoc E, MipsAsmParser &Parser) {
699 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
700 }
701
702 /// Create a register that is definitely an MSACtrl.
703 /// This is typically only used for named registers such as $msaaccess.
704 static MipsOperand *CreateMSACtrlReg(unsigned Index,
705 const MCRegisterInfo *RegInfo, SMLoc S,
706 SMLoc E, MipsAsmParser &Parser) {
707 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
708 }
709
710 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
711 MipsAsmParser &Parser) {
712 MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000713 Op->Imm.Val = Val;
714 Op->StartLoc = S;
715 Op->EndLoc = E;
716 return Op;
717 }
718
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000719 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
720 SMLoc E, MipsAsmParser &Parser) {
721 MipsOperand *Op = new MipsOperand(k_Memory, Parser);
Jack Carterdc1e35d2012-09-06 20:00:02 +0000722 Op->Mem.Base = Base;
723 Op->Mem.Off = Off;
724 Op->StartLoc = S;
725 Op->EndLoc = E;
726 return Op;
727 }
728
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000729 bool isGPRAsmReg() const {
730 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000731 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000732 bool isFGRAsmReg() const {
733 // AFGR64 is $0-$15 but we handle this in getAFGR64()
734 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000735 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000736 bool isHWRegsAsmReg() const {
737 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000738 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000739 bool isCCRAsmReg() const {
740 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000741 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000742 bool isFCCAsmReg() const {
743 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
Jack Carter873c7242013-01-12 01:03:14 +0000744 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000745 bool isACCAsmReg() const {
746 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
Vladimir Medic233dd512013-06-24 10:05:34 +0000747 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000748 bool isCOP2AsmReg() const {
749 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000750 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000751 bool isMSA128AsmReg() const {
752 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000753 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000754 bool isMSACtrlAsmReg() const {
755 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000756 }
757
Jack Carterb4dbc172012-09-05 23:34:03 +0000758 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper56c590a2014-04-29 07:58:02 +0000759 SMLoc getStartLoc() const override { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000760 /// getEndLoc - Get the location of the last token of this operand.
Craig Topper56c590a2014-04-29 07:58:02 +0000761 SMLoc getEndLoc() const override { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000762
NAKAMURA Takumie1f35832014-04-15 14:13:21 +0000763 virtual ~MipsOperand() {
764 switch (Kind) {
765 case k_Immediate:
766 break;
767 case k_Memory:
768 delete Mem.Base;
769 break;
770 case k_PhysRegister:
771 case k_RegisterIndex:
772 case k_Token:
773 break;
774 }
775 }
776
Craig Topper56c590a2014-04-29 07:58:02 +0000777 void print(raw_ostream &OS) const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000778 switch (Kind) {
779 case k_Immediate:
780 OS << "Imm<";
781 Imm.Val->print(OS);
782 OS << ">";
783 break;
784 case k_Memory:
785 OS << "Mem<";
786 Mem.Base->print(OS);
787 OS << ", ";
788 Mem.Off->print(OS);
789 OS << ">";
790 break;
791 case k_PhysRegister:
792 OS << "PhysReg<" << PhysReg.Num << ">";
793 break;
794 case k_RegisterIndex:
795 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
796 break;
797 case k_Token:
798 OS << Tok.Data;
799 break;
800 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000801 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000802}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000803} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000804
Jack Carter9e65aa32013-03-22 00:05:30 +0000805namespace llvm {
806extern const MCInstrDesc MipsInsts[];
807}
808static const MCInstrDesc &getInstDesc(unsigned Opcode) {
809 return MipsInsts[Opcode];
810}
811
812bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000813 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000814 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000815
Jack Carter9e65aa32013-03-22 00:05:30 +0000816 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000817
818 if (MCID.isBranch() || MCID.isCall()) {
819 const unsigned Opcode = Inst.getOpcode();
820 MCOperand Offset;
821
822 switch (Opcode) {
823 default:
824 break;
825 case Mips::BEQ:
826 case Mips::BNE:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000827 case Mips::BEQ_MM:
828 case Mips::BNE_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000829 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000830 Offset = Inst.getOperand(2);
831 if (!Offset.isImm())
832 break; // We'll deal with this situation later on when applying fixups.
833 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
834 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000835 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000836 return Error(IDLoc, "branch to misaligned address");
837 break;
838 case Mips::BGEZ:
839 case Mips::BGTZ:
840 case Mips::BLEZ:
841 case Mips::BLTZ:
842 case Mips::BGEZAL:
843 case Mips::BLTZAL:
844 case Mips::BC1F:
845 case Mips::BC1T:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000846 case Mips::BGEZ_MM:
847 case Mips::BGTZ_MM:
848 case Mips::BLEZ_MM:
849 case Mips::BLTZ_MM:
850 case Mips::BGEZAL_MM:
851 case Mips::BLTZAL_MM:
852 case Mips::BC1F_MM:
853 case Mips::BC1T_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000854 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000855 Offset = Inst.getOperand(1);
856 if (!Offset.isImm())
857 break; // We'll deal with this situation later on when applying fixups.
858 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
859 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000860 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000861 return Error(IDLoc, "branch to misaligned address");
862 break;
863 }
864 }
865
Jack Carterc15c1d22013-04-25 23:31:35 +0000866 if (MCID.hasDelaySlot() && Options.isReorder()) {
867 // If this instruction has a delay slot and .set reorder is active,
868 // emit a NOP after it.
869 Instructions.push_back(Inst);
870 MCInst NopInst;
871 NopInst.setOpcode(Mips::SLL);
872 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
873 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
874 NopInst.addOperand(MCOperand::CreateImm(0));
875 Instructions.push_back(NopInst);
876 return false;
877 }
878
Jack Carter9e65aa32013-03-22 00:05:30 +0000879 if (MCID.mayLoad() || MCID.mayStore()) {
880 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000881 // reference or immediate we may have to expand instructions.
882 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000883 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000884 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
885 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000886 MCOperand &Op = Inst.getOperand(i);
887 if (Op.isImm()) {
888 int MemOffset = Op.getImm();
889 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000890 // Offset can't exceed 16bit value.
891 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000892 return false;
893 }
894 } else if (Op.isExpr()) {
895 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000896 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000897 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000898 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000899 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000900 // Expand symbol.
901 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000902 return false;
903 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000904 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000905 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000906 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000907 }
908 }
909 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000910 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000911 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000912
913 if (needsExpansion(Inst))
914 expandInstruction(Inst, IDLoc, Instructions);
915 else
916 Instructions.push_back(Inst);
917
918 return false;
919}
920
Jack Carter30a59822012-10-04 04:03:53 +0000921bool MipsAsmParser::needsExpansion(MCInst &Inst) {
922
Jack Carterd0bd6422013-04-18 00:41:53 +0000923 switch (Inst.getOpcode()) {
924 case Mips::LoadImm32Reg:
925 case Mips::LoadAddr32Imm:
926 case Mips::LoadAddr32Reg:
927 return true;
928 default:
929 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000930 }
931}
Jack Carter92995f12012-10-06 00:53:28 +0000932
Jack Carter30a59822012-10-04 04:03:53 +0000933void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000934 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000935 switch (Inst.getOpcode()) {
936 case Mips::LoadImm32Reg:
937 return expandLoadImm(Inst, IDLoc, Instructions);
938 case Mips::LoadAddr32Imm:
939 return expandLoadAddressImm(Inst, IDLoc, Instructions);
940 case Mips::LoadAddr32Reg:
941 return expandLoadAddressReg(Inst, IDLoc, Instructions);
942 }
Jack Carter30a59822012-10-04 04:03:53 +0000943}
Jack Carter92995f12012-10-06 00:53:28 +0000944
Jack Carter30a59822012-10-04 04:03:53 +0000945void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000946 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000947 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000948 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000949 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000950 const MCOperand &RegOp = Inst.getOperand(0);
951 assert(RegOp.isReg() && "expected register operand kind");
952
953 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000954 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000955 if (0 <= ImmValue && ImmValue <= 65535) {
956 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000957 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000958 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000959 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000960 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000961 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000962 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000963 } else if (ImmValue < 0 && ImmValue >= -32768) {
964 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000965 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000966 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000967 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000968 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000969 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000970 Instructions.push_back(tmpInst);
971 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000972 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000973 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000974 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000975 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000976 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
977 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000978 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000979 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000980 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000981 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
982 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
983 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
984 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000985 Instructions.push_back(tmpInst);
986 }
987}
Jack Carter92995f12012-10-06 00:53:28 +0000988
Vladimir Medic4c299852013-11-06 11:27:05 +0000989void
990MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
991 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000992 MCInst tmpInst;
993 const MCOperand &ImmOp = Inst.getOperand(2);
994 assert(ImmOp.isImm() && "expected immediate operand kind");
995 const MCOperand &SrcRegOp = Inst.getOperand(1);
996 assert(SrcRegOp.isReg() && "expected register operand kind");
997 const MCOperand &DstRegOp = Inst.getOperand(0);
998 assert(DstRegOp.isReg() && "expected register operand kind");
999 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001000 if (-32768 <= ImmValue && ImmValue <= 65535) {
1001 // For -32768 <= j <= 65535.
1002 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +00001003 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +00001004 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1005 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1006 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1007 Instructions.push_back(tmpInst);
1008 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001009 // For any other value of j that is representable as a 32-bit integer.
1010 // la d,j(s) => lui d,hi16(j)
1011 // ori d,d,lo16(j)
1012 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +00001013 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001014 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1015 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1016 Instructions.push_back(tmpInst);
1017 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001018 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001019 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1020 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1021 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1022 Instructions.push_back(tmpInst);
1023 tmpInst.clear();
1024 tmpInst.setOpcode(Mips::ADDu);
1025 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1026 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1027 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1028 Instructions.push_back(tmpInst);
1029 }
1030}
1031
Vladimir Medic4c299852013-11-06 11:27:05 +00001032void
1033MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1034 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +00001035 MCInst tmpInst;
1036 const MCOperand &ImmOp = Inst.getOperand(1);
1037 assert(ImmOp.isImm() && "expected immediate operand kind");
1038 const MCOperand &RegOp = Inst.getOperand(0);
1039 assert(RegOp.isReg() && "expected register operand kind");
1040 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001041 if (-32768 <= ImmValue && ImmValue <= 65535) {
1042 // For -32768 <= j <= 65535.
1043 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +00001044 tmpInst.setOpcode(Mips::ADDiu);
1045 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +00001046 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +00001047 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1048 Instructions.push_back(tmpInst);
1049 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001050 // For any other value of j that is representable as a 32-bit integer.
1051 // la d,j => lui d,hi16(j)
1052 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +00001053 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001054 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1055 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1056 Instructions.push_back(tmpInst);
1057 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001058 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001059 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1060 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1061 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1062 Instructions.push_back(tmpInst);
1063 }
1064}
1065
Jack Carter9e65aa32013-03-22 00:05:30 +00001066void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +00001067 SmallVectorImpl<MCInst> &Instructions,
1068 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +00001069 const MCSymbolRefExpr *SR;
1070 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +00001071 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +00001072 const MCExpr *ExprOffset;
1073 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +00001074 unsigned AtRegNum = getReg(
Daniel Sanders5e94e682014-03-27 16:42:17 +00001075 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +00001076 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001077 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1078 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001079 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001080 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1081 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001082 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +00001083 if (isImmOpnd) {
1084 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1085 ImmOffset = Inst.getOperand(2).getImm();
1086 LoOffset = ImmOffset & 0x0000ffff;
1087 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +00001088 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +00001089 if (LoOffset & 0x8000)
1090 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +00001091 } else
Jack Carter9e65aa32013-03-22 00:05:30 +00001092 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +00001093 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +00001094 TempInst.setLoc(IDLoc);
1095 // 1st instruction in expansion is LUi. For load instruction we can use
1096 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +00001097 // but for stores we must use $at.
1098 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +00001099 TempInst.setOpcode(Mips::LUi);
1100 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1101 if (isImmOpnd)
1102 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1103 else {
1104 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001105 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +00001106 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1107 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1108 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001109 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001110 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001111 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +00001112 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001113 }
1114 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001115 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +00001116 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +00001117 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +00001118 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +00001119 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001120 TempInst.setOpcode(Mips::ADDu);
1121 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1122 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1123 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1124 Instructions.push_back(TempInst);
1125 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +00001126 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +00001127 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001128 TempInst.setOpcode(Inst.getOpcode());
1129 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1130 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1131 if (isImmOpnd)
1132 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1133 else {
1134 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001135 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1136 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1137 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001138 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001139 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001140 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +00001141 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001142 }
1143 }
1144 Instructions.push_back(TempInst);
1145 TempInst.clear();
1146}
1147
Vladimir Medic4c299852013-11-06 11:27:05 +00001148bool MipsAsmParser::MatchAndEmitInstruction(
1149 SMLoc IDLoc, unsigned &Opcode,
1150 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
1151 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001152 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +00001153 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +00001154 unsigned MatchResult =
1155 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +00001156
1157 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001158 default:
1159 break;
Jack Carterb4dbc172012-09-05 23:34:03 +00001160 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001161 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +00001162 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +00001163 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +00001164 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +00001165 return false;
1166 }
1167 case Match_MissingFeature:
1168 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1169 return true;
1170 case Match_InvalidOperand: {
1171 SMLoc ErrorLoc = IDLoc;
1172 if (ErrorInfo != ~0U) {
1173 if (ErrorInfo >= Operands.size())
1174 return Error(IDLoc, "too few operands for instruction");
1175
Vladimir Medic4c299852013-11-06 11:27:05 +00001176 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001177 if (ErrorLoc == SMLoc())
1178 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +00001179 }
1180
1181 return Error(ErrorLoc, "invalid operand for instruction");
1182 }
1183 case Match_MnemonicFail:
1184 return Error(IDLoc, "invalid instruction");
1185 }
Rafael Espindola870c4e92012-01-11 03:56:41 +00001186 return true;
1187}
1188
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001189void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1190 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1191 if (RegIndex == 1)
1192 Warning(Loc, "Used $at without \".set noat\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001193 else
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001194 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1195 Twine(RegIndex) + "\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001196 }
1197}
1198
Jack Carter1ac53222013-02-20 23:11:17 +00001199int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001200 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +00001201
Vladimir Medic4c299852013-11-06 11:27:05 +00001202 CC = StringSwitch<unsigned>(Name)
1203 .Case("zero", 0)
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001204 .Case("at", 1)
Vladimir Medic4c299852013-11-06 11:27:05 +00001205 .Case("a0", 4)
1206 .Case("a1", 5)
1207 .Case("a2", 6)
1208 .Case("a3", 7)
1209 .Case("v0", 2)
1210 .Case("v1", 3)
1211 .Case("s0", 16)
1212 .Case("s1", 17)
1213 .Case("s2", 18)
1214 .Case("s3", 19)
1215 .Case("s4", 20)
1216 .Case("s5", 21)
1217 .Case("s6", 22)
1218 .Case("s7", 23)
1219 .Case("k0", 26)
1220 .Case("k1", 27)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001221 .Case("gp", 28)
Vladimir Medic4c299852013-11-06 11:27:05 +00001222 .Case("sp", 29)
1223 .Case("fp", 30)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001224 .Case("s8", 30)
Vladimir Medic4c299852013-11-06 11:27:05 +00001225 .Case("ra", 31)
1226 .Case("t0", 8)
1227 .Case("t1", 9)
1228 .Case("t2", 10)
1229 .Case("t3", 11)
1230 .Case("t4", 12)
1231 .Case("t5", 13)
1232 .Case("t6", 14)
1233 .Case("t7", 15)
1234 .Case("t8", 24)
1235 .Case("t9", 25)
1236 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001237
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001238 if (isN32() || isN64()) {
1239 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1240 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1241 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1242 if (8 <= CC && CC <= 11)
1243 CC += 4;
Jack Carter1ac53222013-02-20 23:11:17 +00001244
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001245 if (CC == -1)
1246 CC = StringSwitch<unsigned>(Name)
1247 .Case("a4", 8)
1248 .Case("a5", 9)
1249 .Case("a6", 10)
1250 .Case("a7", 11)
1251 .Case("kt0", 26)
1252 .Case("kt1", 27)
1253 .Default(-1);
1254 }
Jack Carter1ac53222013-02-20 23:11:17 +00001255
1256 return CC;
1257}
Jack Carterd0bd6422013-04-18 00:41:53 +00001258
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001259int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001260
Jack Cartera63b16a2012-09-07 00:23:42 +00001261 if (Name[0] == 'f') {
1262 StringRef NumString = Name.substr(1);
1263 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001264 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001265 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001266 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001267 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001268 return IntVal;
1269 }
1270 return -1;
1271}
Jack Cartera63b16a2012-09-07 00:23:42 +00001272
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001273int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1274
1275 if (Name.startswith("fcc")) {
1276 StringRef NumString = Name.substr(3);
1277 unsigned IntVal;
1278 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001279 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001280 if (IntVal > 7) // There are only 8 fcc registers.
1281 return -1;
1282 return IntVal;
1283 }
1284 return -1;
1285}
1286
1287int MipsAsmParser::matchACRegisterName(StringRef Name) {
1288
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001289 if (Name.startswith("ac")) {
1290 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001291 unsigned IntVal;
1292 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001293 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001294 if (IntVal > 3) // There are only 3 acc registers.
1295 return -1;
1296 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001297 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001298 return -1;
1299}
Jack Carterd0bd6422013-04-18 00:41:53 +00001300
Jack Carter5dc8ac92013-09-25 23:50:44 +00001301int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1302 unsigned IntVal;
1303
1304 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1305 return -1;
1306
1307 if (IntVal > 31)
1308 return -1;
1309
1310 return IntVal;
1311}
1312
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001313int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1314 int CC;
1315
1316 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001317 .Case("msair", 0)
1318 .Case("msacsr", 1)
1319 .Case("msaaccess", 2)
1320 .Case("msasave", 3)
1321 .Case("msamodify", 4)
1322 .Case("msarequest", 5)
1323 .Case("msamap", 6)
1324 .Case("msaunmap", 7)
1325 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001326
1327 return CC;
1328}
1329
Jack Carter0b744b32012-10-04 02:29:46 +00001330bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1331 if (Reg > 31)
1332 return false;
1333
1334 aTReg = Reg;
1335 return true;
1336}
1337
Daniel Sandersd89b1362014-03-24 16:48:01 +00001338int MipsAsmParser::getATReg() {
1339 int AT = Options.getATRegNum();
1340 if (AT == 0)
1341 TokError("Pseudo instruction requires $at, which is not available");
1342 return AT;
1343}
Jack Carter0b744b32012-10-04 02:29:46 +00001344
Jack Carterd0bd6422013-04-18 00:41:53 +00001345unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001346 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001347}
1348
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001349unsigned MipsAsmParser::getGPR(int RegNo) {
Daniel Sanders5e94e682014-03-27 16:42:17 +00001350 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1351 RegNo);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001352}
1353
Jack Carter873c7242013-01-12 01:03:14 +00001354int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001355 if (RegNum >
Daniel Sanders64cf5a42014-03-27 15:00:44 +00001356 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
Jack Carterb4dbc172012-09-05 23:34:03 +00001357 return -1;
1358
Jack Carter873c7242013-01-12 01:03:14 +00001359 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001360}
1361
Vladimir Medic4c299852013-11-06 11:27:05 +00001362bool
1363MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1364 StringRef Mnemonic) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001365 DEBUG(dbgs() << "ParseOperand\n");
1366
Jack Carter30a59822012-10-04 04:03:53 +00001367 // Check if the current operand has a custom associated parser, if so, try to
1368 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001369 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1370 if (ResTy == MatchOperand_Success)
1371 return false;
1372 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1373 // there was a match, but an error occurred, in which case, just return that
1374 // the operand parsing failed.
1375 if (ResTy == MatchOperand_ParseFail)
1376 return true;
1377
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001378 DEBUG(dbgs() << ".. Generic Parser\n");
1379
Jack Carterb4dbc172012-09-05 23:34:03 +00001380 switch (getLexer().getKind()) {
1381 default:
1382 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1383 return true;
1384 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001385 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001386 SMLoc S = Parser.getTok().getLoc();
Jack Carterb4dbc172012-09-05 23:34:03 +00001387
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001388 // Almost all registers have been parsed by custom parsers. There is only
1389 // one exception to this. $zero (and it's alias $0) will reach this point
1390 // for div, divu, and similar instructions because it is not an operand
1391 // to the instruction definition but an explicit register. Special case
1392 // this situation for now.
1393 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
Jack Carterb4dbc172012-09-05 23:34:03 +00001394 return false;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001395
Jack Carterd0bd6422013-04-18 00:41:53 +00001396 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001397 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001398 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001399 return true;
1400
Jack Carter873c7242013-01-12 01:03:14 +00001401 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001402 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001403 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001404 const MCExpr *Res =
1405 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001406
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001407 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001408 return false;
1409 }
Vladimir Medic4c299852013-11-06 11:27:05 +00001410 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001411 case AsmToken::LParen:
1412 case AsmToken::Minus:
1413 case AsmToken::Plus:
1414 case AsmToken::Integer:
1415 case AsmToken::String: {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001416 DEBUG(dbgs() << ".. generic integer\n");
1417 OperandMatchResultTy ResTy = ParseImm(Operands);
1418 return ResTy != MatchOperand_Success;
Jack Carterb4dbc172012-09-05 23:34:03 +00001419 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001420 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001421 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001422 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001423 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001424 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001425 return true;
1426
Jack Carter873c7242013-01-12 01:03:14 +00001427 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1428
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001429 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterdc1e35d2012-09-06 20:00:02 +00001430 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001431 } // case AsmToken::Percent
1432 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001433 return true;
1434}
1435
Vladimir Medic4c299852013-11-06 11:27:05 +00001436const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001437 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001438 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001439 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001440 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Sasa Stankovic06c47802014-04-03 10:37:45 +00001441 // It's a constant, evaluate reloc value.
1442 int16_t Val;
1443 switch (getVariantKind(RelocStr)) {
1444 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1445 // Get the 1st 16-bits.
1446 Val = MCE->getValue() & 0xffff;
1447 break;
1448 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1449 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1450 // 16 bits being negative.
1451 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1452 break;
1453 case MCSymbolRefExpr::VK_Mips_HIGHER:
1454 // Get the 3rd 16-bits.
1455 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1456 break;
1457 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1458 // Get the 4th 16-bits.
1459 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1460 break;
1461 default:
1462 report_fatal_error("Unsupported reloc value!");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001463 }
Sasa Stankovic06c47802014-04-03 10:37:45 +00001464 return MCConstantExpr::Create(Val, getContext());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001465 }
1466
Jack Carterb5cf5902013-04-17 00:18:04 +00001467 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001468 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001469 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001470 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001471 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001472 return Res;
1473 }
1474
1475 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001476 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1477
Sasa Stankovic06c47802014-04-03 10:37:45 +00001478 // Try to create target expression.
1479 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1480 return MipsMCExpr::Create(VK, Expr, getContext());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001481
Jack Carterd0bd6422013-04-18 00:41:53 +00001482 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1483 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001484 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1485 return Res;
1486 }
1487
1488 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001489 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1490 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1491 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001492 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001493 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001494 return Expr;
1495}
1496
1497bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1498
1499 switch (Expr->getKind()) {
1500 case MCExpr::Constant:
1501 return true;
1502 case MCExpr::SymbolRef:
1503 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1504 case MCExpr::Binary:
1505 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1506 if (!isEvaluated(BE->getLHS()))
1507 return false;
1508 return isEvaluated(BE->getRHS());
1509 }
1510 case MCExpr::Unary:
1511 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001512 case MCExpr::Target:
1513 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001514 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001515 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001516}
Jack Carterd0bd6422013-04-18 00:41:53 +00001517
Jack Carterb5cf5902013-04-17 00:18:04 +00001518bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001519 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001520 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001521 if (Tok.isNot(AsmToken::Identifier))
1522 return true;
1523
1524 std::string Str = Tok.getIdentifier().str();
1525
Jack Carterd0bd6422013-04-18 00:41:53 +00001526 Parser.Lex(); // Eat the identifier.
1527 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001528 const MCExpr *IdVal;
1529 SMLoc EndLoc;
1530
1531 if (getLexer().getKind() == AsmToken::LParen) {
1532 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001533 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001534 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001535 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001536 const AsmToken &nextTok = Parser.getTok();
1537 if (nextTok.isNot(AsmToken::Identifier))
1538 return true;
1539 Str += "(%";
1540 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001541 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001542 if (getLexer().getKind() != AsmToken::LParen)
1543 return true;
1544 } else
1545 break;
1546 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001547 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001548 return true;
1549
1550 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001551 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001552
1553 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001554 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001555
Jack Carterd0bd6422013-04-18 00:41:53 +00001556 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001557 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001558}
1559
Jack Carterb4dbc172012-09-05 23:34:03 +00001560bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1561 SMLoc &EndLoc) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001562 SmallVector<MCParsedAsmOperand *, 1> Operands;
1563 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1564 if (ResTy == MatchOperand_Success) {
1565 assert(Operands.size() == 1);
1566 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
1567 StartLoc = Operand.getStartLoc();
1568 EndLoc = Operand.getEndLoc();
1569
1570 // AFAIK, we only support numeric registers and named GPR's in CFI
1571 // directives.
1572 // Don't worry about eating tokens before failing. Using an unrecognised
1573 // register is a parse error.
1574 if (Operand.isGPRAsmReg()) {
1575 // Resolve to GPR32 or GPR64 appropriately.
1576 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1577 }
1578
NAKAMURA Takumibd524ef2014-04-15 14:06:27 +00001579 delete &Operand;
1580
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001581 return (RegNo == (unsigned)-1);
1582 }
1583
1584 assert(Operands.size() == 0);
Vladimir Medic4c299852013-11-06 11:27:05 +00001585 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001586}
1587
Jack Carterb5cf5902013-04-17 00:18:04 +00001588bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001589 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001590 bool Result = true;
1591
1592 while (getLexer().getKind() == AsmToken::LParen)
1593 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001594
Jack Carterd0bd6422013-04-18 00:41:53 +00001595 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001596 default:
1597 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001598 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001599 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001600 case AsmToken::Integer:
1601 case AsmToken::Minus:
1602 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001603 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001604 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001605 else
1606 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001607 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001608 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001609 break;
Jack Carter873c7242013-01-12 01:03:14 +00001610 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001611 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001612 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001613 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001614}
1615
Jack Carterb4dbc172012-09-05 23:34:03 +00001616MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001617 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001618 DEBUG(dbgs() << "parseMemOperand\n");
Craig Topper062a2ba2014-04-25 05:30:21 +00001619 const MCExpr *IdVal = nullptr;
Jack Carter873c7242013-01-12 01:03:14 +00001620 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001621 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001622 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001623 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001624 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001625
Jack Carterb5cf5902013-04-17 00:18:04 +00001626 if (getLexer().getKind() == AsmToken::LParen) {
1627 Parser.Lex();
1628 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001629 }
1630
Jack Carterb5cf5902013-04-17 00:18:04 +00001631 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001632 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001633 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001634
Jack Carterd0bd6422013-04-18 00:41:53 +00001635 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001636 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001637 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001638 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001639 SMLoc E =
1640 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001641 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001642 return MatchOperand_Success;
1643 }
1644 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001645 SMLoc E =
1646 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001647
Jack Carterd0bd6422013-04-18 00:41:53 +00001648 // Zero register assumed, add a memory operand with ZERO as its base.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001649 // "Base" will be managed by k_Memory.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001650 MipsOperand *Base = MipsOperand::CreateGPRReg(
1651 0, getContext().getRegisterInfo(), S, E, *this);
1652 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001653 return MatchOperand_Success;
1654 }
1655 Error(Parser.getTok().getLoc(), "'(' expected");
1656 return MatchOperand_ParseFail;
1657 }
1658
Jack Carterd0bd6422013-04-18 00:41:53 +00001659 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001660 }
1661
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001662 Res = ParseAnyRegister(Operands);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001663 if (Res != MatchOperand_Success)
1664 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001665
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001666 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001667 Error(Parser.getTok().getLoc(), "')' expected");
1668 return MatchOperand_ParseFail;
1669 }
1670
Jack Carter873c7242013-01-12 01:03:14 +00001671 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1672
Jack Carterd0bd6422013-04-18 00:41:53 +00001673 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001674
Craig Topper062a2ba2014-04-25 05:30:21 +00001675 if (!IdVal)
Jack Carterdc1e35d2012-09-06 20:00:02 +00001676 IdVal = MCConstantExpr::Create(0, getContext());
1677
Jack Carterd0bd6422013-04-18 00:41:53 +00001678 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001679 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterd0bd6422013-04-18 00:41:53 +00001680 // Remove the register from the operands.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001681 // "op" will be managed by k_Memory.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001682 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001683 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001684 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1685 int64_t Imm;
1686 if (IdVal->EvaluateAsAbsolute(Imm))
1687 IdVal = MCConstantExpr::Create(Imm, getContext());
1688 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1689 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1690 getContext());
1691 }
1692
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001693 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001694 return MatchOperand_Success;
1695}
1696
Daniel Sanderse34a1202014-03-31 18:51:43 +00001697bool MipsAsmParser::searchSymbolAlias(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001698 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001699
Jack Carterd76b2372013-03-21 21:44:16 +00001700 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1701 if (Sym) {
1702 SMLoc S = Parser.getTok().getLoc();
1703 const MCExpr *Expr;
1704 if (Sym->isVariable())
1705 Expr = Sym->getVariableValue();
1706 else
1707 return false;
1708 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001709 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00001710 const StringRef DefSymbol = Ref->getSymbol().getName();
1711 if (DefSymbol.startswith("$")) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001712 OperandMatchResultTy ResTy =
1713 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
Daniel Sanders09934572014-04-01 10:37:46 +00001714 if (ResTy == MatchOperand_Success) {
1715 Parser.Lex();
Jack Carterd76b2372013-03-21 21:44:16 +00001716 return true;
Daniel Sanders09934572014-04-01 10:37:46 +00001717 } else if (ResTy == MatchOperand_ParseFail)
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001718 llvm_unreachable("Should never ParseFail");
1719 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001720 }
1721 } else if (Expr->getKind() == MCExpr::Constant) {
1722 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00001723 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1724 MipsOperand *op =
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001725 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
Jack Carterd76b2372013-03-21 21:44:16 +00001726 Operands.push_back(op);
1727 return true;
1728 }
1729 }
1730 return false;
1731}
Jack Carterd0bd6422013-04-18 00:41:53 +00001732
Jack Carter873c7242013-01-12 01:03:14 +00001733MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001734MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
1735 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
1736 SMLoc S) {
1737 int Index = matchCPURegisterName(Identifier);
1738 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001739 Operands.push_back(MipsOperand::CreateGPRReg(
1740 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1741 return MatchOperand_Success;
1742 }
1743
1744 Index = matchFPURegisterName(Identifier);
1745 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001746 Operands.push_back(MipsOperand::CreateFGRReg(
1747 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1748 return MatchOperand_Success;
1749 }
1750
1751 Index = matchFCCRegisterName(Identifier);
1752 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001753 Operands.push_back(MipsOperand::CreateFCCReg(
1754 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1755 return MatchOperand_Success;
1756 }
1757
1758 Index = matchACRegisterName(Identifier);
1759 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001760 Operands.push_back(MipsOperand::CreateACCReg(
1761 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1762 return MatchOperand_Success;
1763 }
1764
1765 Index = matchMSA128RegisterName(Identifier);
1766 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001767 Operands.push_back(MipsOperand::CreateMSA128Reg(
1768 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1769 return MatchOperand_Success;
1770 }
1771
1772 Index = matchMSA128CtrlRegisterName(Identifier);
1773 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001774 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1775 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1776 return MatchOperand_Success;
1777 }
1778
1779 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001780}
1781
1782MipsAsmParser::OperandMatchResultTy
Daniel Sanders21bce302014-04-01 12:35:23 +00001783MipsAsmParser::MatchAnyRegisterWithoutDollar(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001784 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
Daniel Sanders315386c2014-04-01 10:40:14 +00001785 auto Token = Parser.getLexer().peekTok(false);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001786
1787 if (Token.is(AsmToken::Identifier)) {
1788 DEBUG(dbgs() << ".. identifier\n");
1789 StringRef Identifier = Token.getIdentifier();
Daniel Sanders09934572014-04-01 10:37:46 +00001790 OperandMatchResultTy ResTy =
1791 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
Daniel Sanders09934572014-04-01 10:37:46 +00001792 return ResTy;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001793 } else if (Token.is(AsmToken::Integer)) {
1794 DEBUG(dbgs() << ".. integer\n");
1795 Operands.push_back(MipsOperand::CreateNumericReg(
1796 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
1797 *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001798 return MatchOperand_Success;
1799 }
1800
1801 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
1802
1803 return MatchOperand_NoMatch;
1804}
1805
1806MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
1807 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1808 DEBUG(dbgs() << "ParseAnyRegister\n");
1809
1810 auto Token = Parser.getTok();
1811
1812 SMLoc S = Token.getLoc();
1813
1814 if (Token.isNot(AsmToken::Dollar)) {
1815 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
1816 if (Token.is(AsmToken::Identifier)) {
1817 if (searchSymbolAlias(Operands))
1818 return MatchOperand_Success;
1819 }
1820 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
1821 return MatchOperand_NoMatch;
1822 }
1823 DEBUG(dbgs() << ".. $\n");
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001824
Daniel Sanders21bce302014-04-01 12:35:23 +00001825 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
Daniel Sanders315386c2014-04-01 10:40:14 +00001826 if (ResTy == MatchOperand_Success) {
1827 Parser.Lex(); // $
1828 Parser.Lex(); // identifier
1829 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001830 return ResTy;
1831}
1832
1833MipsAsmParser::OperandMatchResultTy
1834MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1835 switch (getLexer().getKind()) {
1836 default:
1837 return MatchOperand_NoMatch;
1838 case AsmToken::LParen:
1839 case AsmToken::Minus:
1840 case AsmToken::Plus:
1841 case AsmToken::Integer:
1842 case AsmToken::String:
1843 break;
1844 }
1845
1846 const MCExpr *IdVal;
1847 SMLoc S = Parser.getTok().getLoc();
1848 if (getParser().parseExpression(IdVal))
1849 return MatchOperand_ParseFail;
1850
1851 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1852 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1853 return MatchOperand_Success;
1854}
1855
1856MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
1857 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1858 DEBUG(dbgs() << "ParseJumpTarget\n");
1859
1860 SMLoc S = getLexer().getLoc();
1861
1862 // Integers and expressions are acceptable
1863 OperandMatchResultTy ResTy = ParseImm(Operands);
1864 if (ResTy != MatchOperand_NoMatch)
1865 return ResTy;
1866
Daniel Sanders315386c2014-04-01 10:40:14 +00001867 // Registers are a valid target and have priority over symbols.
1868 ResTy = ParseAnyRegister(Operands);
1869 if (ResTy != MatchOperand_NoMatch)
1870 return ResTy;
1871
Daniel Sandersffd84362014-04-01 10:41:48 +00001872 const MCExpr *Expr = nullptr;
1873 if (Parser.parseExpression(Expr)) {
1874 // We have no way of knowing if a symbol was consumed so we must ParseFail
1875 return MatchOperand_ParseFail;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001876 }
Daniel Sandersffd84362014-04-01 10:41:48 +00001877 Operands.push_back(
1878 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001879 return MatchOperand_Success;
Jack Carter873c7242013-01-12 01:03:14 +00001880}
1881
Vladimir Medic2b953d02013-10-01 09:48:56 +00001882MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001883MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00001884 const MCExpr *IdVal;
1885 // If the first token is '$' we may have register operand.
1886 if (Parser.getTok().is(AsmToken::Dollar))
1887 return MatchOperand_NoMatch;
1888 SMLoc S = Parser.getTok().getLoc();
1889 if (getParser().parseExpression(IdVal))
1890 return MatchOperand_ParseFail;
1891 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00001892 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00001893 int64_t Val = MCE->getValue();
1894 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1895 Operands.push_back(MipsOperand::CreateImm(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001896 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
Vladimir Medic2b953d02013-10-01 09:48:56 +00001897 return MatchOperand_Success;
1898}
1899
Matheus Almeida779c5932013-11-18 12:32:49 +00001900MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001901MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Matheus Almeida779c5932013-11-18 12:32:49 +00001902 switch (getLexer().getKind()) {
1903 default:
1904 return MatchOperand_NoMatch;
1905 case AsmToken::LParen:
1906 case AsmToken::Plus:
1907 case AsmToken::Minus:
1908 case AsmToken::Integer:
1909 break;
1910 }
1911
1912 const MCExpr *Expr;
1913 SMLoc S = Parser.getTok().getLoc();
1914
1915 if (getParser().parseExpression(Expr))
1916 return MatchOperand_ParseFail;
1917
1918 int64_t Val;
1919 if (!Expr->EvaluateAsAbsolute(Val)) {
1920 Error(S, "expected immediate value");
1921 return MatchOperand_ParseFail;
1922 }
1923
1924 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
1925 // and because the CPU always adds one to the immediate field, the allowed
1926 // range becomes 1..4. We'll only check the range here and will deal
1927 // with the addition/subtraction when actually decoding/encoding
1928 // the instruction.
1929 if (Val < 1 || Val > 4) {
1930 Error(S, "immediate not in range (1..4)");
1931 return MatchOperand_ParseFail;
1932 }
1933
Jack Carter3b2c96e2014-01-22 23:31:38 +00001934 Operands.push_back(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001935 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
Matheus Almeida779c5932013-11-18 12:32:49 +00001936 return MatchOperand_Success;
1937}
1938
Jack Carterdc1e35d2012-09-06 20:00:02 +00001939MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1940
Vladimir Medic4c299852013-11-06 11:27:05 +00001941 MCSymbolRefExpr::VariantKind VK =
1942 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1943 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1944 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1945 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1946 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1947 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1948 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1949 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1950 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1951 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1952 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1953 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1954 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1955 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1956 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1957 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1958 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1959 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
Daniel Sandersa567da52014-03-31 15:15:02 +00001960 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
1961 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
1962 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
1963 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
1964 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
1965 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
Vladimir Medic4c299852013-11-06 11:27:05 +00001966 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001967
Matheus Almeida2852af82014-04-22 10:15:54 +00001968 assert(VK != MCSymbolRefExpr::VK_None);
Daniel Sandersa567da52014-03-31 15:15:02 +00001969
Jack Carterdc1e35d2012-09-06 20:00:02 +00001970 return VK;
1971}
Jack Cartera63b16a2012-09-07 00:23:42 +00001972
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001973/// Sometimes (i.e. load/stores) the operand may be followed immediately by
1974/// either this.
1975/// ::= '(', register, ')'
1976/// handle it before we iterate so we don't get tripped up by the lack of
1977/// a comma.
1978bool MipsAsmParser::ParseParenSuffix(
1979 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1980 if (getLexer().is(AsmToken::LParen)) {
1981 Operands.push_back(
1982 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
1983 Parser.Lex();
1984 if (ParseOperand(Operands, Name)) {
1985 SMLoc Loc = getLexer().getLoc();
1986 Parser.eatToEndOfStatement();
1987 return Error(Loc, "unexpected token in argument list");
1988 }
1989 if (Parser.getTok().isNot(AsmToken::RParen)) {
1990 SMLoc Loc = getLexer().getLoc();
1991 Parser.eatToEndOfStatement();
1992 return Error(Loc, "unexpected token, expected ')'");
1993 }
1994 Operands.push_back(
1995 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
1996 Parser.Lex();
1997 }
1998 return false;
1999}
2000
2001/// Sometimes (i.e. in MSA) the operand may be followed immediately by
2002/// either one of these.
2003/// ::= '[', register, ']'
2004/// ::= '[', integer, ']'
2005/// handle it before we iterate so we don't get tripped up by the lack of
2006/// a comma.
2007bool MipsAsmParser::ParseBracketSuffix(
2008 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2009 if (getLexer().is(AsmToken::LBrac)) {
2010 Operands.push_back(
2011 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2012 Parser.Lex();
2013 if (ParseOperand(Operands, Name)) {
2014 SMLoc Loc = getLexer().getLoc();
2015 Parser.eatToEndOfStatement();
2016 return Error(Loc, "unexpected token in argument list");
2017 }
2018 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2019 SMLoc Loc = getLexer().getLoc();
2020 Parser.eatToEndOfStatement();
2021 return Error(Loc, "unexpected token, expected ']'");
2022 }
2023 Operands.push_back(
2024 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2025 Parser.Lex();
2026 }
2027 return false;
2028}
2029
Vladimir Medic4c299852013-11-06 11:27:05 +00002030bool MipsAsmParser::ParseInstruction(
2031 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2032 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002033 DEBUG(dbgs() << "ParseInstruction\n");
Vladimir Medic74593e62013-07-17 15:00:42 +00002034 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002035 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002036 Parser.eatToEndOfStatement();
2037 return Error(NameLoc, "Unknown instruction");
2038 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002039 // First operand in MCInst is instruction mnemonic.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002040 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00002041
2042 // Read the remaining operands.
2043 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2044 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002045 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002046 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002047 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002048 return Error(Loc, "unexpected token in argument list");
2049 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002050 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2051 return true;
2052 // AFAIK, parenthesis suffixes are never on the first operand
Jack Carterb4dbc172012-09-05 23:34:03 +00002053
Jack Carterd0bd6422013-04-18 00:41:53 +00002054 while (getLexer().is(AsmToken::Comma)) {
2055 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002056 // Parse and remember the operand.
2057 if (ParseOperand(Operands, Name)) {
2058 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002059 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002060 return Error(Loc, "unexpected token in argument list");
2061 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002062 // Parse bracket and parenthesis suffixes before we iterate
2063 if (getLexer().is(AsmToken::LBrac)) {
2064 if (ParseBracketSuffix(Name, Operands))
2065 return true;
2066 } else if (getLexer().is(AsmToken::LParen) &&
2067 ParseParenSuffix(Name, Operands))
2068 return true;
Jack Carterb4dbc172012-09-05 23:34:03 +00002069 }
2070 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002071 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2072 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002073 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002074 return Error(Loc, "unexpected token in argument list");
2075 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002076 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002077 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002078}
2079
Jack Carter0b744b32012-10-04 02:29:46 +00002080bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002081 SMLoc Loc = getLexer().getLoc();
2082 Parser.eatToEndOfStatement();
2083 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002084}
2085
2086bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002087 // Line should look like: ".set noat".
2088 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002089 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002090 // eat noat
2091 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002092 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002093 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2094 reportParseError("unexpected token in statement");
2095 return false;
2096 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002097 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002098 return false;
2099}
Jack Carterd0bd6422013-04-18 00:41:53 +00002100
Jack Carter0b744b32012-10-04 02:29:46 +00002101bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002102 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002103 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002104 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002105 getParser().Lex();
2106 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002107 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002108 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002109 return false;
2110 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002111 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002112 if (getLexer().isNot(AsmToken::Dollar)) {
2113 reportParseError("unexpected token in statement");
2114 return false;
2115 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002116 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002117 const AsmToken &Reg = Parser.getTok();
2118 if (Reg.is(AsmToken::Identifier)) {
2119 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2120 } else if (Reg.is(AsmToken::Integer)) {
2121 AtRegNo = Reg.getIntVal();
2122 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002123 reportParseError("unexpected token in statement");
2124 return false;
2125 }
Jack Carter1ac53222013-02-20 23:11:17 +00002126
Daniel Sanders71a89d922014-03-25 13:01:06 +00002127 if (AtRegNo < 0 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002128 reportParseError("unexpected token in statement");
2129 return false;
2130 }
2131
2132 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002133 reportParseError("unexpected token in statement");
2134 return false;
2135 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002136 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002137
2138 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2139 reportParseError("unexpected token in statement");
2140 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002141 }
2142 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002143 return false;
2144 } else {
2145 reportParseError("unexpected token in statement");
2146 return false;
2147 }
2148}
2149
2150bool MipsAsmParser::parseSetReorderDirective() {
2151 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002152 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002153 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2154 reportParseError("unexpected token in statement");
2155 return false;
2156 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002157 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002158 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002159 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002160 return false;
2161}
2162
2163bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002164 Parser.Lex();
2165 // If this is not the end of the statement, report an error.
2166 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2167 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002168 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002169 }
2170 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002171 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002172 Parser.Lex(); // Consume the EndOfStatement.
2173 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002174}
2175
2176bool MipsAsmParser::parseSetMacroDirective() {
2177 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002178 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002179 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2180 reportParseError("unexpected token in statement");
2181 return false;
2182 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002183 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002184 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002185 return false;
2186}
2187
2188bool MipsAsmParser::parseSetNoMacroDirective() {
2189 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002190 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002191 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2192 reportParseError("`noreorder' must be set before `nomacro'");
2193 return false;
2194 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002195 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002196 reportParseError("`noreorder' must be set before `nomacro'");
2197 return false;
2198 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002199 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002200 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002201 return false;
2202}
Jack Carterd76b2372013-03-21 21:44:16 +00002203
Jack Carter39536722014-01-22 23:08:42 +00002204bool MipsAsmParser::parseSetNoMips16Directive() {
2205 Parser.Lex();
2206 // If this is not the end of the statement, report an error.
2207 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2208 reportParseError("unexpected token in statement");
2209 return false;
2210 }
2211 // For now do nothing.
2212 Parser.Lex(); // Consume the EndOfStatement.
2213 return false;
2214}
2215
Jack Carterd76b2372013-03-21 21:44:16 +00002216bool MipsAsmParser::parseSetAssignment() {
2217 StringRef Name;
2218 const MCExpr *Value;
2219
2220 if (Parser.parseIdentifier(Name))
2221 reportParseError("expected identifier after .set");
2222
2223 if (getLexer().isNot(AsmToken::Comma))
2224 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002225 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002226
Jack Carter3b2c96e2014-01-22 23:31:38 +00002227 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002228 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002229
Jack Carterd0bd6422013-04-18 00:41:53 +00002230 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002231 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002232 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002233 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002234 Sym = getContext().GetOrCreateSymbol(Name);
2235 Sym->setVariableValue(Value);
2236
2237 return false;
2238}
Jack Carterd0bd6422013-04-18 00:41:53 +00002239
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002240bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2241 Parser.Lex();
2242 if (getLexer().isNot(AsmToken::EndOfStatement))
2243 return reportParseError("unexpected token in .set directive");
2244
Matheus Almeida2852af82014-04-22 10:15:54 +00002245 switch (Feature) {
2246 default:
2247 llvm_unreachable("Unimplemented feature");
2248 case Mips::FeatureDSP:
2249 setFeatureBits(Mips::FeatureDSP, "dsp");
2250 getTargetStreamer().emitDirectiveSetDsp();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002251 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002252 case Mips::FeatureMicroMips:
2253 getTargetStreamer().emitDirectiveSetMicroMips();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002254 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002255 case Mips::FeatureMips16:
2256 getTargetStreamer().emitDirectiveSetMips16();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002257 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002258 case Mips::FeatureMips32r2:
2259 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2260 getTargetStreamer().emitDirectiveSetMips32R2();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002261 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002262 case Mips::FeatureMips64:
2263 setFeatureBits(Mips::FeatureMips64, "mips64");
2264 getTargetStreamer().emitDirectiveSetMips64();
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002265 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002266 case Mips::FeatureMips64r2:
2267 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2268 getTargetStreamer().emitDirectiveSetMips64R2();
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002269 break;
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002270 }
2271 return false;
2272}
2273
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002274bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2275 if (!getLexer().is(AsmToken::Dollar))
2276 return false;
2277
2278 Parser.Lex();
2279
2280 const AsmToken &Reg = Parser.getTok();
2281 if (Reg.is(AsmToken::Identifier)) {
2282 RegNum = matchCPURegisterName(Reg.getIdentifier());
2283 } else if (Reg.is(AsmToken::Integer)) {
2284 RegNum = Reg.getIntVal();
2285 } else {
2286 return false;
2287 }
2288
2289 Parser.Lex();
2290 return true;
2291}
2292
2293bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2294 if (getLexer().isNot(AsmToken::Comma)) {
2295 SMLoc Loc = getLexer().getLoc();
2296 Parser.eatToEndOfStatement();
2297 return Error(Loc, ErrorStr);
2298 }
2299
Matheus Almeida2852af82014-04-22 10:15:54 +00002300 Parser.Lex(); // Eat the comma.
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002301 return true;
2302}
2303
2304bool MipsAsmParser::parseDirectiveCPSetup() {
2305 unsigned FuncReg;
2306 unsigned Save;
2307 bool SaveIsReg = true;
2308
2309 if (!parseRegister(FuncReg))
2310 return reportParseError("expected register containing function address");
2311 FuncReg = getGPR(FuncReg);
2312
2313 if (!eatComma("expected comma parsing directive"))
2314 return true;
2315
2316 if (!parseRegister(Save)) {
2317 const AsmToken &Tok = Parser.getTok();
2318 if (Tok.is(AsmToken::Integer)) {
2319 Save = Tok.getIntVal();
2320 SaveIsReg = false;
2321 Parser.Lex();
2322 } else
2323 return reportParseError("expected save register or stack offset");
2324 } else
2325 Save = getGPR(Save);
2326
2327 if (!eatComma("expected comma parsing directive"))
2328 return true;
2329
2330 StringRef Name;
2331 if (Parser.parseIdentifier(Name))
2332 reportParseError("expected identifier");
2333 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2334 unsigned GPReg = getGPR(matchCPURegisterName("gp"));
2335
2336 // FIXME: The code below this point should be in the TargetStreamers.
2337 // Only N32 and N64 emit anything for .cpsetup
2338 // FIXME: We should only emit something for PIC mode too.
2339 if (!isN32() && !isN64())
2340 return false;
2341
2342 MCStreamer &TS = getStreamer();
2343 MCInst Inst;
2344 // Either store the old $gp in a register or on the stack
2345 if (SaveIsReg) {
2346 // move $save, $gpreg
2347 Inst.setOpcode(Mips::DADDu);
2348 Inst.addOperand(MCOperand::CreateReg(Save));
2349 Inst.addOperand(MCOperand::CreateReg(GPReg));
2350 Inst.addOperand(MCOperand::CreateReg(getGPR(0)));
2351 } else {
2352 // sd $gpreg, offset($sp)
2353 Inst.setOpcode(Mips::SD);
2354 Inst.addOperand(MCOperand::CreateReg(GPReg));
2355 Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp"))));
2356 Inst.addOperand(MCOperand::CreateImm(Save));
2357 }
2358 TS.EmitInstruction(Inst, STI);
2359 Inst.clear();
2360
2361 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
Matheus Almeida2852af82014-04-22 10:15:54 +00002362 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, getContext());
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002363 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
Matheus Almeida2852af82014-04-22 10:15:54 +00002364 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, getContext());
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002365 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
2366 Inst.setOpcode(Mips::LUi);
2367 Inst.addOperand(MCOperand::CreateReg(GPReg));
2368 Inst.addOperand(MCOperand::CreateExpr(HiExpr));
2369 TS.EmitInstruction(Inst, STI);
2370 Inst.clear();
2371
2372 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
2373 Inst.setOpcode(Mips::ADDiu);
2374 Inst.addOperand(MCOperand::CreateReg(GPReg));
2375 Inst.addOperand(MCOperand::CreateReg(GPReg));
2376 Inst.addOperand(MCOperand::CreateExpr(LoExpr));
2377 TS.EmitInstruction(Inst, STI);
2378 Inst.clear();
2379
2380 // daddu $gp, $gp, $funcreg
2381 Inst.setOpcode(Mips::DADDu);
2382 Inst.addOperand(MCOperand::CreateReg(GPReg));
2383 Inst.addOperand(MCOperand::CreateReg(GPReg));
2384 Inst.addOperand(MCOperand::CreateReg(FuncReg));
2385 TS.EmitInstruction(Inst, STI);
2386 return false;
2387}
2388
Matheus Almeida0051f2d2014-04-16 15:48:55 +00002389bool MipsAsmParser::parseDirectiveNaN() {
2390 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2391 const AsmToken &Tok = Parser.getTok();
2392
2393 if (Tok.getString() == "2008") {
2394 Parser.Lex();
2395 getTargetStreamer().emitDirectiveNaN2008();
2396 return false;
2397 } else if (Tok.getString() == "legacy") {
2398 Parser.Lex();
2399 getTargetStreamer().emitDirectiveNaNLegacy();
2400 return false;
2401 }
2402 }
2403 // If we don't recognize the option passed to the .nan
2404 // directive (e.g. no option or unknown option), emit an error.
2405 reportParseError("invalid option in .nan directive");
2406 return false;
2407}
2408
Jack Carter0b744b32012-10-04 02:29:46 +00002409bool MipsAsmParser::parseDirectiveSet() {
2410
Jack Carterd0bd6422013-04-18 00:41:53 +00002411 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002412 const AsmToken &Tok = Parser.getTok();
2413
2414 if (Tok.getString() == "noat") {
2415 return parseSetNoAtDirective();
2416 } else if (Tok.getString() == "at") {
2417 return parseSetAtDirective();
2418 } else if (Tok.getString() == "reorder") {
2419 return parseSetReorderDirective();
2420 } else if (Tok.getString() == "noreorder") {
2421 return parseSetNoReorderDirective();
2422 } else if (Tok.getString() == "macro") {
2423 return parseSetMacroDirective();
2424 } else if (Tok.getString() == "nomacro") {
2425 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002426 } else if (Tok.getString() == "mips16") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002427 return parseSetFeature(Mips::FeatureMips16);
Jack Carter0b744b32012-10-04 02:29:46 +00002428 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002429 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002430 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002431 getTargetStreamer().emitDirectiveSetNoMicroMips();
2432 Parser.eatToEndOfStatement();
2433 return false;
2434 } else if (Tok.getString() == "micromips") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002435 return parseSetFeature(Mips::FeatureMicroMips);
Vladimir Medic615b26e2014-03-04 09:54:09 +00002436 } else if (Tok.getString() == "mips32r2") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002437 return parseSetFeature(Mips::FeatureMips32r2);
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002438 } else if (Tok.getString() == "mips64") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002439 return parseSetFeature(Mips::FeatureMips64);
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002440 } else if (Tok.getString() == "mips64r2") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002441 return parseSetFeature(Mips::FeatureMips64r2);
Vladimir Medic27c398e2014-03-05 11:05:09 +00002442 } else if (Tok.getString() == "dsp") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002443 return parseSetFeature(Mips::FeatureDSP);
Jack Carterd76b2372013-03-21 21:44:16 +00002444 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002445 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002446 parseSetAssignment();
2447 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002448 }
Jack Carter07c818d2013-01-25 01:31:34 +00002449
Jack Carter0b744b32012-10-04 02:29:46 +00002450 return true;
2451}
2452
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002453/// parseDataDirective
Jack Carter07c818d2013-01-25 01:31:34 +00002454/// ::= .word [ expression (, expression)* ]
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002455bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
Jack Carter07c818d2013-01-25 01:31:34 +00002456 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2457 for (;;) {
2458 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002459 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002460 return true;
2461
2462 getParser().getStreamer().EmitValue(Value, Size);
2463
2464 if (getLexer().is(AsmToken::EndOfStatement))
2465 break;
2466
2467 // FIXME: Improve diagnostic.
2468 if (getLexer().isNot(AsmToken::Comma))
2469 return Error(L, "unexpected token in directive");
2470 Parser.Lex();
2471 }
2472 }
2473
2474 Parser.Lex();
2475 return false;
2476}
2477
Vladimir Medic4c299852013-11-06 11:27:05 +00002478/// parseDirectiveGpWord
2479/// ::= .gpword local_sym
2480bool MipsAsmParser::parseDirectiveGpWord() {
2481 const MCExpr *Value;
2482 // EmitGPRel32Value requires an expression, so we are using base class
2483 // method to evaluate the expression.
2484 if (getParser().parseExpression(Value))
2485 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002486 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002487
Vladimir Medice10c1122013-11-13 13:18:04 +00002488 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002489 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002490 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002491 return false;
2492}
2493
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002494/// parseDirectiveGpDWord
Rafael Espindolab59fb732014-03-28 18:50:26 +00002495/// ::= .gpdword local_sym
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002496bool MipsAsmParser::parseDirectiveGpDWord() {
Rafael Espindolab59fb732014-03-28 18:50:26 +00002497 const MCExpr *Value;
2498 // EmitGPRel64Value requires an expression, so we are using base class
2499 // method to evaluate the expression.
2500 if (getParser().parseExpression(Value))
2501 return true;
2502 getParser().getStreamer().EmitGPRel64Value(Value);
2503
2504 if (getLexer().isNot(AsmToken::EndOfStatement))
2505 return Error(getLexer().getLoc(), "unexpected token in directive");
2506 Parser.Lex(); // Eat EndOfStatement token.
2507 return false;
2508}
2509
Jack Carter0cd3c192014-01-06 23:27:31 +00002510bool MipsAsmParser::parseDirectiveOption() {
2511 // Get the option token.
2512 AsmToken Tok = Parser.getTok();
2513 // At the moment only identifiers are supported.
2514 if (Tok.isNot(AsmToken::Identifier)) {
2515 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2516 Parser.eatToEndOfStatement();
2517 return false;
2518 }
2519
2520 StringRef Option = Tok.getIdentifier();
2521
2522 if (Option == "pic0") {
2523 getTargetStreamer().emitDirectiveOptionPic0();
2524 Parser.Lex();
2525 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2526 Error(Parser.getTok().getLoc(),
2527 "unexpected token in .option pic0 directive");
2528 Parser.eatToEndOfStatement();
2529 }
2530 return false;
2531 }
2532
Matheus Almeidaf79b2812014-03-26 13:40:29 +00002533 if (Option == "pic2") {
2534 getTargetStreamer().emitDirectiveOptionPic2();
2535 Parser.Lex();
2536 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2537 Error(Parser.getTok().getLoc(),
2538 "unexpected token in .option pic2 directive");
2539 Parser.eatToEndOfStatement();
2540 }
2541 return false;
2542 }
2543
Jack Carter0cd3c192014-01-06 23:27:31 +00002544 // Unknown option.
2545 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2546 Parser.eatToEndOfStatement();
2547 return false;
2548}
2549
Jack Carter0b744b32012-10-04 02:29:46 +00002550bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002551 StringRef IDVal = DirectiveID.getString();
2552
Matheus Almeidaab5633b2014-03-26 15:44:18 +00002553 if (IDVal == ".dword") {
2554 parseDataDirective(8, DirectiveID.getLoc());
2555 return false;
2556 }
2557
Jack Carterd0bd6422013-04-18 00:41:53 +00002558 if (IDVal == ".ent") {
2559 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002560 Parser.Lex();
2561 return false;
2562 }
2563
Jack Carter07c818d2013-01-25 01:31:34 +00002564 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002565 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002566 Parser.Lex();
2567 return false;
2568 }
2569
Jack Carter07c818d2013-01-25 01:31:34 +00002570 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002571 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002572 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002573 return false;
2574 }
2575
Jack Carter07c818d2013-01-25 01:31:34 +00002576 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002577 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002578 }
2579
Jack Carter07c818d2013-01-25 01:31:34 +00002580 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002581 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002582 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002583 return false;
2584 }
2585
Jack Carter07c818d2013-01-25 01:31:34 +00002586 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002587 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002588 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002589 return false;
2590 }
2591
Matheus Almeida0051f2d2014-04-16 15:48:55 +00002592 if (IDVal == ".nan")
2593 return parseDirectiveNaN();
2594
Jack Carter07c818d2013-01-25 01:31:34 +00002595 if (IDVal == ".gpword") {
Vladimir Medic4c299852013-11-06 11:27:05 +00002596 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002597 return false;
2598 }
2599
Rafael Espindolab59fb732014-03-28 18:50:26 +00002600 if (IDVal == ".gpdword") {
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002601 parseDirectiveGpDWord();
Rafael Espindolab59fb732014-03-28 18:50:26 +00002602 return false;
2603 }
2604
Jack Carter07c818d2013-01-25 01:31:34 +00002605 if (IDVal == ".word") {
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002606 parseDataDirective(4, DirectiveID.getLoc());
Jack Carter07c818d2013-01-25 01:31:34 +00002607 return false;
2608 }
2609
Jack Carter0cd3c192014-01-06 23:27:31 +00002610 if (IDVal == ".option")
2611 return parseDirectiveOption();
2612
2613 if (IDVal == ".abicalls") {
2614 getTargetStreamer().emitDirectiveAbiCalls();
2615 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2616 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2617 // Clear line
2618 Parser.eatToEndOfStatement();
2619 }
2620 return false;
2621 }
2622
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002623 if (IDVal == ".cpsetup")
2624 return parseDirectiveCPSetup();
2625
Rafael Espindola870c4e92012-01-11 03:56:41 +00002626 return true;
2627}
2628
Rafael Espindola870c4e92012-01-11 03:56:41 +00002629extern "C" void LLVMInitializeMipsAsmParser() {
2630 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2631 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2632 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2633 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2634}
Jack Carterb4dbc172012-09-05 23:34:03 +00002635
2636#define GET_REGISTER_MATCHER
2637#define GET_MATCHER_IMPLEMENTATION
2638#include "MipsGenAsmMatcher.inc"