blob: 86fd386967f9fd9bc4de00b4b0ff40082a1eb886 [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);
Matheus Almeida525bc4f2014-04-30 11:28:42 +0000140 bool reportParseError(SMLoc Loc, StringRef ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +0000141
Jack Carterb5cf5902013-04-17 00:18:04 +0000142 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000143 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000144
Vladimir Medic4c299852013-11-06 11:27:05 +0000145 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000146
147 bool isEvaluated(const MCExpr *Expr);
Matheus Almeidafe1e39d2014-03-26 14:26:27 +0000148 bool parseSetFeature(uint64_t Feature);
Matheus Almeida525bc4f2014-04-30 11:28:42 +0000149 bool parseDirectiveCPLoad(SMLoc Loc);
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000150 bool parseDirectiveCPSetup();
Matheus Almeida0051f2d2014-04-16 15:48:55 +0000151 bool parseDirectiveNaN();
Jack Carter0b744b32012-10-04 02:29:46 +0000152 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000153 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000154
155 bool parseSetAtDirective();
156 bool parseSetNoAtDirective();
157 bool parseSetMacroDirective();
158 bool parseSetNoMacroDirective();
159 bool parseSetReorderDirective();
160 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000161 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000162
Jack Carterd76b2372013-03-21 21:44:16 +0000163 bool parseSetAssignment();
164
Matheus Almeida3e2a7022014-03-26 15:24:36 +0000165 bool parseDataDirective(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000166 bool parseDirectiveGpWord();
Rafael Espindola2378d4c2014-03-31 14:15:07 +0000167 bool parseDirectiveGpDWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000168
Jack Carterdc1e35d2012-09-06 20:00:02 +0000169 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000170
Daniel Sanders5e94e682014-03-27 16:42:17 +0000171 bool isGP64() const {
172 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
Jack Carterb4dbc172012-09-05 23:34:03 +0000173 }
174
Jack Cartera63b16a2012-09-07 00:23:42 +0000175 bool isFP64() const {
176 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
177 }
178
Daniel Sandersa4b0c742014-03-26 11:39:07 +0000179 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
Vladimir Medic4c299852013-11-06 11:27:05 +0000180 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000181
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000182 bool isMicroMips() const {
183 return STI.getFeatureBits() & Mips::FeatureMicroMips;
184 }
185
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000186 bool parseRegister(unsigned &RegNum);
187
188 bool eatComma(StringRef ErrorStr);
189
Jack Carter1ac53222013-02-20 23:11:17 +0000190 int matchCPURegisterName(StringRef Symbol);
191
Jack Carter873c7242013-01-12 01:03:14 +0000192 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000193
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000194 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000195
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000196 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000197
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000198 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000199
Jack Carter5dc8ac92013-09-25 23:50:44 +0000200 int matchMSA128RegisterName(StringRef Name);
201
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000202 int matchMSA128CtrlRegisterName(StringRef Name);
203
Jack Carterd0bd6422013-04-18 00:41:53 +0000204 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000205
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000206 unsigned getGPR(int RegNo);
207
Jack Carter1ac53222013-02-20 23:11:17 +0000208 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000209
210 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000211 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000212
213 // Helper function that checks if the value of a vector index is within the
214 // boundaries of accepted values for each RegisterKind
215 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
216 bool validateMSAIndex(int Val, int RegKind);
217
Vladimir Medic615b26e2014-03-04 09:54:09 +0000218 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
219 if (!(STI.getFeatureBits() & Feature)) {
Matheus Almeida2852af82014-04-22 10:15:54 +0000220 setAvailableFeatures(
221 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
Vladimir Medic615b26e2014-03-04 09:54:09 +0000222 }
223 }
224
225 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
226 if (STI.getFeatureBits() & Feature) {
Matheus Almeida2852af82014-04-22 10:15:54 +0000227 setAvailableFeatures(
228 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
Vladimir Medic615b26e2014-03-04 09:54:09 +0000229 }
230 }
231
Rafael Espindola870c4e92012-01-11 03:56:41 +0000232public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000233 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
Evgeniy Stepanov0a951b72014-04-23 11:16:03 +0000234 const MCInstrInfo &MII,
235 const MCTargetOptions &Options)
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000236 : MCTargetAsmParser(), STI(sti), Parser(parser) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000237 // Initialize the set of available features.
238 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000239
240 // Assert exactly one ABI was chosen.
241 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
242 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
243 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
244 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000245 }
246
Jack Carterb4dbc172012-09-05 23:34:03 +0000247 MCAsmParser &getParser() const { return Parser; }
248 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000249
250 /// Warn if RegNo is the current assembler temporary.
251 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000252};
253}
254
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000255namespace {
256
257/// MipsOperand - Instances of this class represent a parsed Mips machine
258/// instruction.
259class MipsOperand : public MCParsedAsmOperand {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000260public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000261 /// Broad categories of register classes
262 /// The exact class is finalized by the render method.
263 enum RegKind {
264 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64())
265 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
266 /// isFP64())
267 RegKind_FCC = 4, /// FCC
268 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
269 RegKind_MSACtrl = 16, /// MSA control registers
270 RegKind_COP2 = 32, /// COP2
271 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
272 /// context).
273 RegKind_CCR = 128, /// CCR
274 RegKind_HWRegs = 256, /// HWRegs
Daniel Sanderscdbbe082014-05-08 13:02:11 +0000275 RegKind_COP3 = 512, /// COP3
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000276
277 /// Potentially any (e.g. $1)
278 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
279 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
Daniel Sanderscdbbe082014-05-08 13:02:11 +0000280 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
Jack Carter873c7242013-01-12 01:03:14 +0000281 };
282
283private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000284 enum KindTy {
Daniel Sanders21bce302014-04-01 12:35:23 +0000285 k_Immediate, /// An immediate (possibly involving symbol references)
286 k_Memory, /// Base + Offset Memory Address
287 k_PhysRegister, /// A physical register from the Mips namespace
288 k_RegisterIndex, /// A register index in one or more RegKind.
289 k_Token /// A simple token
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000290 } Kind;
291
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000292 MipsOperand(KindTy K, MipsAsmParser &Parser)
293 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
294
295 /// For diagnostics, and checking the assembler temporary
296 MipsAsmParser &AsmParser;
Jack Carterb4dbc172012-09-05 23:34:03 +0000297
Eric Christopher8996c5d2013-03-15 00:42:55 +0000298 struct Token {
299 const char *Data;
300 unsigned Length;
301 };
302
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000303 struct PhysRegOp {
304 unsigned Num; /// Register Number
305 };
306
307 struct RegIdxOp {
308 unsigned Index; /// Index into the register class
309 RegKind Kind; /// Bitfield of the kinds it could possibly be
310 const MCRegisterInfo *RegInfo;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000311 };
312
313 struct ImmOp {
314 const MCExpr *Val;
315 };
316
317 struct MemOp {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000318 MipsOperand *Base;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000319 const MCExpr *Off;
320 };
321
Jack Carterb4dbc172012-09-05 23:34:03 +0000322 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000323 struct Token Tok;
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000324 struct PhysRegOp PhysReg;
325 struct RegIdxOp RegIdx;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000326 struct ImmOp Imm;
327 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000328 };
329
330 SMLoc StartLoc, EndLoc;
331
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000332 /// Internal constructor for register kinds
333 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
334 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
335 MipsAsmParser &Parser) {
336 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
337 Op->RegIdx.Index = Index;
338 Op->RegIdx.RegInfo = RegInfo;
339 Op->RegIdx.Kind = RegKind;
340 Op->StartLoc = S;
341 Op->EndLoc = E;
342 return Op;
343 }
344
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000345public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000346 /// Coerce the register to GPR32 and return the real register for the current
347 /// target.
348 unsigned getGPR32Reg() const {
349 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
350 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
351 unsigned ClassID = Mips::GPR32RegClassID;
352 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000353 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000354
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000355 /// Coerce the register to GPR64 and return the real register for the current
356 /// target.
357 unsigned getGPR64Reg() const {
358 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
359 unsigned ClassID = Mips::GPR64RegClassID;
360 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000361 }
362
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000363private:
364 /// Coerce the register to AFGR64 and return the real register for the current
365 /// target.
366 unsigned getAFGR64Reg() const {
367 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
368 if (RegIdx.Index % 2 != 0)
369 AsmParser.Warning(StartLoc, "Float register should be even.");
370 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
371 .getRegister(RegIdx.Index / 2);
372 }
373
374 /// Coerce the register to FGR64 and return the real register for the current
375 /// target.
376 unsigned getFGR64Reg() const {
377 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
378 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
379 .getRegister(RegIdx.Index);
380 }
381
382 /// Coerce the register to FGR32 and return the real register for the current
383 /// target.
384 unsigned getFGR32Reg() const {
385 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
386 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
387 .getRegister(RegIdx.Index);
388 }
389
390 /// Coerce the register to FGRH32 and return the real register for the current
391 /// target.
392 unsigned getFGRH32Reg() const {
393 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
394 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
395 .getRegister(RegIdx.Index);
396 }
397
398 /// Coerce the register to FCC and return the real register for the current
399 /// target.
400 unsigned getFCCReg() const {
401 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
402 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
403 .getRegister(RegIdx.Index);
404 }
405
406 /// Coerce the register to MSA128 and return the real register for the current
407 /// target.
408 unsigned getMSA128Reg() const {
409 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
410 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
411 // identical
412 unsigned ClassID = Mips::MSA128BRegClassID;
413 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
414 }
415
416 /// Coerce the register to MSACtrl and return the real register for the
417 /// current target.
418 unsigned getMSACtrlReg() const {
419 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
420 unsigned ClassID = Mips::MSACtrlRegClassID;
421 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
422 }
423
424 /// Coerce the register to COP2 and return the real register for the
425 /// current target.
426 unsigned getCOP2Reg() const {
427 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
428 unsigned ClassID = Mips::COP2RegClassID;
429 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
430 }
431
Daniel Sanderscdbbe082014-05-08 13:02:11 +0000432 /// Coerce the register to COP3 and return the real register for the
433 /// current target.
434 unsigned getCOP3Reg() const {
435 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
436 unsigned ClassID = Mips::COP3RegClassID;
437 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
438 }
439
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000440 /// Coerce the register to ACC64DSP and return the real register for the
441 /// current target.
442 unsigned getACC64DSPReg() const {
443 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
444 unsigned ClassID = Mips::ACC64DSPRegClassID;
445 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
446 }
447
448 /// Coerce the register to HI32DSP and return the real register for the
449 /// current target.
450 unsigned getHI32DSPReg() const {
451 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
452 unsigned ClassID = Mips::HI32DSPRegClassID;
453 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
454 }
455
456 /// Coerce the register to LO32DSP and return the real register for the
457 /// current target.
458 unsigned getLO32DSPReg() const {
459 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
460 unsigned ClassID = Mips::LO32DSPRegClassID;
461 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
462 }
463
464 /// Coerce the register to CCR and return the real register for the
465 /// current target.
466 unsigned getCCRReg() const {
467 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
468 unsigned ClassID = Mips::CCRRegClassID;
469 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
470 }
471
472 /// Coerce the register to HWRegs and return the real register for the
473 /// current target.
474 unsigned getHWRegsReg() const {
475 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
476 unsigned ClassID = Mips::HWRegsRegClassID;
477 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
478 }
479
480public:
Vladimir Medic4c299852013-11-06 11:27:05 +0000481 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000482 // Add as immediate when possible. Null MCExpr = 0.
Craig Topper062a2ba2014-04-25 05:30:21 +0000483 if (!Expr)
Jack Carterb4dbc172012-09-05 23:34:03 +0000484 Inst.addOperand(MCOperand::CreateImm(0));
485 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
486 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
487 else
488 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000489 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000490
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000491 void addRegOperands(MCInst &Inst, unsigned N) const {
492 llvm_unreachable("Use a custom parser instead");
493 }
494
Daniel Sanders21bce302014-04-01 12:35:23 +0000495 /// Render the operand to an MCInst as a GPR32
496 /// Asserts if the wrong number of operands are requested, or the operand
497 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000498 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
499 assert(N == 1 && "Invalid number of operands!");
500 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
501 }
502
Daniel Sanders21bce302014-04-01 12:35:23 +0000503 /// Render the operand to an MCInst as a GPR64
504 /// Asserts if the wrong number of operands are requested, or the operand
505 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000506 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
507 assert(N == 1 && "Invalid number of operands!");
508 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
509 }
510
511 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
512 assert(N == 1 && "Invalid number of operands!");
513 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
514 }
515
516 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
517 assert(N == 1 && "Invalid number of operands!");
518 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
519 }
520
521 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
522 assert(N == 1 && "Invalid number of operands!");
523 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
524 }
525
526 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
527 assert(N == 1 && "Invalid number of operands!");
528 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
529 }
530
531 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
532 assert(N == 1 && "Invalid number of operands!");
533 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
534 }
535
536 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
537 assert(N == 1 && "Invalid number of operands!");
538 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
539 }
540
541 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
542 assert(N == 1 && "Invalid number of operands!");
543 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
544 }
545
546 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
547 assert(N == 1 && "Invalid number of operands!");
548 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
549 }
550
Daniel Sanderscdbbe082014-05-08 13:02:11 +0000551 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
552 assert(N == 1 && "Invalid number of operands!");
553 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
554 }
555
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000556 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
557 assert(N == 1 && "Invalid number of operands!");
558 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
559 }
560
561 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
562 assert(N == 1 && "Invalid number of operands!");
563 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
564 }
565
566 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
567 assert(N == 1 && "Invalid number of operands!");
568 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
569 }
570
571 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
572 assert(N == 1 && "Invalid number of operands!");
573 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
574 }
575
576 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
577 assert(N == 1 && "Invalid number of operands!");
578 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
579 }
580
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000581 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000582 assert(N == 1 && "Invalid number of operands!");
583 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000584 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000585 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000586
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000587 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000588 assert(N == 2 && "Invalid number of operands!");
589
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000590 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
Jack Carterdc1e35d2012-09-06 20:00:02 +0000591
592 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000593 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000594 }
595
Craig Topper56c590a2014-04-29 07:58:02 +0000596 bool isReg() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000597 // As a special case until we sort out the definition of div/divu, pretend
598 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
599 if (isGPRAsmReg() && RegIdx.Index == 0)
600 return true;
601
602 return Kind == k_PhysRegister;
603 }
604 bool isRegIdx() const { return Kind == k_RegisterIndex; }
Craig Topper56c590a2014-04-29 07:58:02 +0000605 bool isImm() const override { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000606 bool isConstantImm() const {
607 return isImm() && dyn_cast<MCConstantExpr>(getImm());
608 }
Craig Topper56c590a2014-04-29 07:58:02 +0000609 bool isToken() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000610 // Note: It's not possible to pretend that other operand kinds are tokens.
611 // The matcher emitter checks tokens first.
612 return Kind == k_Token;
613 }
Craig Topper56c590a2014-04-29 07:58:02 +0000614 bool isMem() const override { return Kind == k_Memory; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000615 bool isInvNum() const { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000616 bool isLSAImm() const {
617 if (!isConstantImm())
618 return false;
619 int64_t Val = getConstantImm();
620 return 1 <= Val && Val <= 4;
621 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000622
623 StringRef getToken() const {
624 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000625 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000626 }
627
Craig Topper56c590a2014-04-29 07:58:02 +0000628 unsigned getReg() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000629 // As a special case until we sort out the definition of div/divu, pretend
630 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
631 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
632 RegIdx.Kind & RegKind_GPR)
633 return getGPR32Reg(); // FIXME: GPR64 too
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000634
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000635 assert(Kind == k_PhysRegister && "Invalid access!");
636 return PhysReg.Num;
Jack Carter873c7242013-01-12 01:03:14 +0000637 }
638
Jack Carterb4dbc172012-09-05 23:34:03 +0000639 const MCExpr *getImm() const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000640 assert((Kind == k_Immediate) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000641 return Imm.Val;
642 }
643
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000644 int64_t getConstantImm() const {
645 const MCExpr *Val = getImm();
646 return static_cast<const MCConstantExpr *>(Val)->getValue();
647 }
648
649 MipsOperand *getMemBase() const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000650 assert((Kind == k_Memory) && "Invalid access!");
651 return Mem.Base;
652 }
653
654 const MCExpr *getMemOff() const {
655 assert((Kind == k_Memory) && "Invalid access!");
656 return Mem.Off;
657 }
658
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000659 static MipsOperand *CreateToken(StringRef Str, SMLoc S,
660 MipsAsmParser &Parser) {
661 MipsOperand *Op = new MipsOperand(k_Token, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000662 Op->Tok.Data = Str.data();
663 Op->Tok.Length = Str.size();
664 Op->StartLoc = S;
665 Op->EndLoc = S;
666 return Op;
667 }
668
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000669 /// Create a numeric register (e.g. $1). The exact register remains
670 /// unresolved until an instruction successfully matches
671 static MipsOperand *CreateNumericReg(unsigned Index,
672 const MCRegisterInfo *RegInfo, SMLoc S,
673 SMLoc E, MipsAsmParser &Parser) {
674 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
675 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000676 }
677
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000678 /// Create a register that is definitely a GPR.
679 /// This is typically only used for named registers such as $gp.
680 static MipsOperand *CreateGPRReg(unsigned Index,
681 const MCRegisterInfo *RegInfo, SMLoc S,
682 SMLoc E, MipsAsmParser &Parser) {
683 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000684 }
685
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000686 /// Create a register that is definitely a FGR.
687 /// This is typically only used for named registers such as $f0.
688 static MipsOperand *CreateFGRReg(unsigned Index,
689 const MCRegisterInfo *RegInfo, SMLoc S,
690 SMLoc E, MipsAsmParser &Parser) {
691 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
692 }
693
694 /// Create a register that is definitely an FCC.
695 /// This is typically only used for named registers such as $fcc0.
696 static MipsOperand *CreateFCCReg(unsigned Index,
697 const MCRegisterInfo *RegInfo, SMLoc S,
698 SMLoc E, MipsAsmParser &Parser) {
699 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
700 }
701
702 /// Create a register that is definitely an ACC.
703 /// This is typically only used for named registers such as $ac0.
704 static MipsOperand *CreateACCReg(unsigned Index,
705 const MCRegisterInfo *RegInfo, SMLoc S,
706 SMLoc E, MipsAsmParser &Parser) {
707 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
708 }
709
710 /// Create a register that is definitely an MSA128.
711 /// This is typically only used for named registers such as $w0.
712 static MipsOperand *CreateMSA128Reg(unsigned Index,
713 const MCRegisterInfo *RegInfo, SMLoc S,
714 SMLoc E, MipsAsmParser &Parser) {
715 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
716 }
717
718 /// Create a register that is definitely an MSACtrl.
719 /// This is typically only used for named registers such as $msaaccess.
720 static MipsOperand *CreateMSACtrlReg(unsigned Index,
721 const MCRegisterInfo *RegInfo, SMLoc S,
722 SMLoc E, MipsAsmParser &Parser) {
723 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
724 }
725
726 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
727 MipsAsmParser &Parser) {
728 MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000729 Op->Imm.Val = Val;
730 Op->StartLoc = S;
731 Op->EndLoc = E;
732 return Op;
733 }
734
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000735 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
736 SMLoc E, MipsAsmParser &Parser) {
737 MipsOperand *Op = new MipsOperand(k_Memory, Parser);
Jack Carterdc1e35d2012-09-06 20:00:02 +0000738 Op->Mem.Base = Base;
739 Op->Mem.Off = Off;
740 Op->StartLoc = S;
741 Op->EndLoc = E;
742 return Op;
743 }
744
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000745 bool isGPRAsmReg() const {
746 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000747 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000748 bool isFGRAsmReg() const {
749 // AFGR64 is $0-$15 but we handle this in getAFGR64()
750 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000751 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000752 bool isHWRegsAsmReg() const {
753 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000754 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000755 bool isCCRAsmReg() const {
756 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000757 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000758 bool isFCCAsmReg() const {
759 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
Jack Carter873c7242013-01-12 01:03:14 +0000760 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000761 bool isACCAsmReg() const {
762 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
Vladimir Medic233dd512013-06-24 10:05:34 +0000763 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000764 bool isCOP2AsmReg() const {
765 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000766 }
Daniel Sanderscdbbe082014-05-08 13:02:11 +0000767 bool isCOP3AsmReg() const {
768 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
769 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000770 bool isMSA128AsmReg() const {
771 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000772 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000773 bool isMSACtrlAsmReg() const {
774 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000775 }
776
Jack Carterb4dbc172012-09-05 23:34:03 +0000777 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper56c590a2014-04-29 07:58:02 +0000778 SMLoc getStartLoc() const override { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000779 /// getEndLoc - Get the location of the last token of this operand.
Craig Topper56c590a2014-04-29 07:58:02 +0000780 SMLoc getEndLoc() const override { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000781
NAKAMURA Takumie1f35832014-04-15 14:13:21 +0000782 virtual ~MipsOperand() {
783 switch (Kind) {
784 case k_Immediate:
785 break;
786 case k_Memory:
787 delete Mem.Base;
788 break;
789 case k_PhysRegister:
790 case k_RegisterIndex:
791 case k_Token:
792 break;
793 }
794 }
795
Craig Topper56c590a2014-04-29 07:58:02 +0000796 void print(raw_ostream &OS) const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000797 switch (Kind) {
798 case k_Immediate:
799 OS << "Imm<";
800 Imm.Val->print(OS);
801 OS << ">";
802 break;
803 case k_Memory:
804 OS << "Mem<";
805 Mem.Base->print(OS);
806 OS << ", ";
807 Mem.Off->print(OS);
808 OS << ">";
809 break;
810 case k_PhysRegister:
811 OS << "PhysReg<" << PhysReg.Num << ">";
812 break;
813 case k_RegisterIndex:
814 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
815 break;
816 case k_Token:
817 OS << Tok.Data;
818 break;
819 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000820 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000821}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000822} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000823
Jack Carter9e65aa32013-03-22 00:05:30 +0000824namespace llvm {
825extern const MCInstrDesc MipsInsts[];
826}
827static const MCInstrDesc &getInstDesc(unsigned Opcode) {
828 return MipsInsts[Opcode];
829}
830
831bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000832 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000833 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000834
Jack Carter9e65aa32013-03-22 00:05:30 +0000835 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000836
837 if (MCID.isBranch() || MCID.isCall()) {
838 const unsigned Opcode = Inst.getOpcode();
839 MCOperand Offset;
840
841 switch (Opcode) {
842 default:
843 break;
844 case Mips::BEQ:
845 case Mips::BNE:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000846 case Mips::BEQ_MM:
847 case Mips::BNE_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000848 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000849 Offset = Inst.getOperand(2);
850 if (!Offset.isImm())
851 break; // We'll deal with this situation later on when applying fixups.
852 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
853 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000854 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000855 return Error(IDLoc, "branch to misaligned address");
856 break;
857 case Mips::BGEZ:
858 case Mips::BGTZ:
859 case Mips::BLEZ:
860 case Mips::BLTZ:
861 case Mips::BGEZAL:
862 case Mips::BLTZAL:
863 case Mips::BC1F:
864 case Mips::BC1T:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000865 case Mips::BGEZ_MM:
866 case Mips::BGTZ_MM:
867 case Mips::BLEZ_MM:
868 case Mips::BLTZ_MM:
869 case Mips::BGEZAL_MM:
870 case Mips::BLTZAL_MM:
871 case Mips::BC1F_MM:
872 case Mips::BC1T_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000873 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000874 Offset = Inst.getOperand(1);
875 if (!Offset.isImm())
876 break; // We'll deal with this situation later on when applying fixups.
877 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
878 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000879 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000880 return Error(IDLoc, "branch to misaligned address");
881 break;
882 }
883 }
884
Jack Carterc15c1d22013-04-25 23:31:35 +0000885 if (MCID.hasDelaySlot() && Options.isReorder()) {
886 // If this instruction has a delay slot and .set reorder is active,
887 // emit a NOP after it.
888 Instructions.push_back(Inst);
889 MCInst NopInst;
890 NopInst.setOpcode(Mips::SLL);
891 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
892 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
893 NopInst.addOperand(MCOperand::CreateImm(0));
894 Instructions.push_back(NopInst);
895 return false;
896 }
897
Jack Carter9e65aa32013-03-22 00:05:30 +0000898 if (MCID.mayLoad() || MCID.mayStore()) {
899 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000900 // reference or immediate we may have to expand instructions.
901 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000902 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000903 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
904 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000905 MCOperand &Op = Inst.getOperand(i);
906 if (Op.isImm()) {
907 int MemOffset = Op.getImm();
908 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000909 // Offset can't exceed 16bit value.
910 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000911 return false;
912 }
913 } else if (Op.isExpr()) {
914 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000915 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000916 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000917 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000918 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000919 // Expand symbol.
920 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000921 return false;
922 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000923 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000924 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000925 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000926 }
927 }
928 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000929 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000930 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000931
932 if (needsExpansion(Inst))
933 expandInstruction(Inst, IDLoc, Instructions);
934 else
935 Instructions.push_back(Inst);
936
937 return false;
938}
939
Jack Carter30a59822012-10-04 04:03:53 +0000940bool MipsAsmParser::needsExpansion(MCInst &Inst) {
941
Jack Carterd0bd6422013-04-18 00:41:53 +0000942 switch (Inst.getOpcode()) {
943 case Mips::LoadImm32Reg:
944 case Mips::LoadAddr32Imm:
945 case Mips::LoadAddr32Reg:
946 return true;
947 default:
948 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000949 }
950}
Jack Carter92995f12012-10-06 00:53:28 +0000951
Jack Carter30a59822012-10-04 04:03:53 +0000952void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000953 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000954 switch (Inst.getOpcode()) {
955 case Mips::LoadImm32Reg:
956 return expandLoadImm(Inst, IDLoc, Instructions);
957 case Mips::LoadAddr32Imm:
958 return expandLoadAddressImm(Inst, IDLoc, Instructions);
959 case Mips::LoadAddr32Reg:
960 return expandLoadAddressReg(Inst, IDLoc, Instructions);
961 }
Jack Carter30a59822012-10-04 04:03:53 +0000962}
Jack Carter92995f12012-10-06 00:53:28 +0000963
Jack Carter30a59822012-10-04 04:03:53 +0000964void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000965 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000966 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000967 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000968 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000969 const MCOperand &RegOp = Inst.getOperand(0);
970 assert(RegOp.isReg() && "expected register operand kind");
971
972 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000973 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000974 if (0 <= ImmValue && ImmValue <= 65535) {
975 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000976 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000977 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000978 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000979 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000980 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000981 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000982 } else if (ImmValue < 0 && ImmValue >= -32768) {
983 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000984 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000985 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000986 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000987 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000988 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000989 Instructions.push_back(tmpInst);
990 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000991 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000992 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000993 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000994 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000995 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
996 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000997 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000998 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000999 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +00001000 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1001 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1002 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1003 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +00001004 Instructions.push_back(tmpInst);
1005 }
1006}
Jack Carter92995f12012-10-06 00:53:28 +00001007
Vladimir Medic4c299852013-11-06 11:27:05 +00001008void
1009MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1010 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +00001011 MCInst tmpInst;
1012 const MCOperand &ImmOp = Inst.getOperand(2);
1013 assert(ImmOp.isImm() && "expected immediate operand kind");
1014 const MCOperand &SrcRegOp = Inst.getOperand(1);
1015 assert(SrcRegOp.isReg() && "expected register operand kind");
1016 const MCOperand &DstRegOp = Inst.getOperand(0);
1017 assert(DstRegOp.isReg() && "expected register operand kind");
1018 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001019 if (-32768 <= ImmValue && ImmValue <= 65535) {
1020 // For -32768 <= j <= 65535.
1021 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +00001022 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +00001023 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1024 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1025 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1026 Instructions.push_back(tmpInst);
1027 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001028 // For any other value of j that is representable as a 32-bit integer.
1029 // la d,j(s) => lui d,hi16(j)
1030 // ori d,d,lo16(j)
1031 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +00001032 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001033 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1034 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1035 Instructions.push_back(tmpInst);
1036 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001037 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001038 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1039 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1040 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1041 Instructions.push_back(tmpInst);
1042 tmpInst.clear();
1043 tmpInst.setOpcode(Mips::ADDu);
1044 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1045 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1046 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1047 Instructions.push_back(tmpInst);
1048 }
1049}
1050
Vladimir Medic4c299852013-11-06 11:27:05 +00001051void
1052MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1053 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +00001054 MCInst tmpInst;
1055 const MCOperand &ImmOp = Inst.getOperand(1);
1056 assert(ImmOp.isImm() && "expected immediate operand kind");
1057 const MCOperand &RegOp = Inst.getOperand(0);
1058 assert(RegOp.isReg() && "expected register operand kind");
1059 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001060 if (-32768 <= ImmValue && ImmValue <= 65535) {
1061 // For -32768 <= j <= 65535.
1062 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +00001063 tmpInst.setOpcode(Mips::ADDiu);
1064 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +00001065 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +00001066 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1067 Instructions.push_back(tmpInst);
1068 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001069 // For any other value of j that is representable as a 32-bit integer.
1070 // la d,j => lui d,hi16(j)
1071 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +00001072 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001073 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1074 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1075 Instructions.push_back(tmpInst);
1076 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001077 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001078 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1079 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1080 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1081 Instructions.push_back(tmpInst);
1082 }
1083}
1084
Jack Carter9e65aa32013-03-22 00:05:30 +00001085void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +00001086 SmallVectorImpl<MCInst> &Instructions,
1087 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +00001088 const MCSymbolRefExpr *SR;
1089 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +00001090 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +00001091 const MCExpr *ExprOffset;
1092 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +00001093 unsigned AtRegNum = getReg(
Daniel Sanders5e94e682014-03-27 16:42:17 +00001094 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +00001095 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001096 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1097 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001098 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001099 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1100 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001101 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +00001102 if (isImmOpnd) {
1103 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1104 ImmOffset = Inst.getOperand(2).getImm();
1105 LoOffset = ImmOffset & 0x0000ffff;
1106 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +00001107 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +00001108 if (LoOffset & 0x8000)
1109 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +00001110 } else
Jack Carter9e65aa32013-03-22 00:05:30 +00001111 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +00001112 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +00001113 TempInst.setLoc(IDLoc);
1114 // 1st instruction in expansion is LUi. For load instruction we can use
1115 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +00001116 // but for stores we must use $at.
1117 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +00001118 TempInst.setOpcode(Mips::LUi);
1119 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1120 if (isImmOpnd)
1121 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1122 else {
1123 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001124 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +00001125 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1126 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1127 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001128 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001129 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001130 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +00001131 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001132 }
1133 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001134 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +00001135 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +00001136 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +00001137 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +00001138 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001139 TempInst.setOpcode(Mips::ADDu);
1140 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1141 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1142 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1143 Instructions.push_back(TempInst);
1144 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +00001145 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +00001146 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001147 TempInst.setOpcode(Inst.getOpcode());
1148 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1149 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1150 if (isImmOpnd)
1151 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1152 else {
1153 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001154 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1155 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1156 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001157 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001158 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001159 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +00001160 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001161 }
1162 }
1163 Instructions.push_back(TempInst);
1164 TempInst.clear();
1165}
1166
Vladimir Medic4c299852013-11-06 11:27:05 +00001167bool MipsAsmParser::MatchAndEmitInstruction(
1168 SMLoc IDLoc, unsigned &Opcode,
1169 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
1170 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001171 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +00001172 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +00001173 unsigned MatchResult =
1174 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +00001175
1176 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001177 default:
1178 break;
Jack Carterb4dbc172012-09-05 23:34:03 +00001179 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001180 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +00001181 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +00001182 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +00001183 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +00001184 return false;
1185 }
1186 case Match_MissingFeature:
1187 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1188 return true;
1189 case Match_InvalidOperand: {
1190 SMLoc ErrorLoc = IDLoc;
1191 if (ErrorInfo != ~0U) {
1192 if (ErrorInfo >= Operands.size())
1193 return Error(IDLoc, "too few operands for instruction");
1194
Vladimir Medic4c299852013-11-06 11:27:05 +00001195 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001196 if (ErrorLoc == SMLoc())
1197 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +00001198 }
1199
1200 return Error(ErrorLoc, "invalid operand for instruction");
1201 }
1202 case Match_MnemonicFail:
1203 return Error(IDLoc, "invalid instruction");
1204 }
Rafael Espindola870c4e92012-01-11 03:56:41 +00001205 return true;
1206}
1207
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001208void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1209 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1210 if (RegIndex == 1)
1211 Warning(Loc, "Used $at without \".set noat\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001212 else
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001213 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1214 Twine(RegIndex) + "\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001215 }
1216}
1217
Jack Carter1ac53222013-02-20 23:11:17 +00001218int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001219 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +00001220
Vladimir Medic4c299852013-11-06 11:27:05 +00001221 CC = StringSwitch<unsigned>(Name)
1222 .Case("zero", 0)
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001223 .Case("at", 1)
Vladimir Medic4c299852013-11-06 11:27:05 +00001224 .Case("a0", 4)
1225 .Case("a1", 5)
1226 .Case("a2", 6)
1227 .Case("a3", 7)
1228 .Case("v0", 2)
1229 .Case("v1", 3)
1230 .Case("s0", 16)
1231 .Case("s1", 17)
1232 .Case("s2", 18)
1233 .Case("s3", 19)
1234 .Case("s4", 20)
1235 .Case("s5", 21)
1236 .Case("s6", 22)
1237 .Case("s7", 23)
1238 .Case("k0", 26)
1239 .Case("k1", 27)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001240 .Case("gp", 28)
Vladimir Medic4c299852013-11-06 11:27:05 +00001241 .Case("sp", 29)
1242 .Case("fp", 30)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001243 .Case("s8", 30)
Vladimir Medic4c299852013-11-06 11:27:05 +00001244 .Case("ra", 31)
1245 .Case("t0", 8)
1246 .Case("t1", 9)
1247 .Case("t2", 10)
1248 .Case("t3", 11)
1249 .Case("t4", 12)
1250 .Case("t5", 13)
1251 .Case("t6", 14)
1252 .Case("t7", 15)
1253 .Case("t8", 24)
1254 .Case("t9", 25)
1255 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001256
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001257 if (isN32() || isN64()) {
1258 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1259 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1260 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1261 if (8 <= CC && CC <= 11)
1262 CC += 4;
Jack Carter1ac53222013-02-20 23:11:17 +00001263
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001264 if (CC == -1)
1265 CC = StringSwitch<unsigned>(Name)
1266 .Case("a4", 8)
1267 .Case("a5", 9)
1268 .Case("a6", 10)
1269 .Case("a7", 11)
1270 .Case("kt0", 26)
1271 .Case("kt1", 27)
1272 .Default(-1);
1273 }
Jack Carter1ac53222013-02-20 23:11:17 +00001274
1275 return CC;
1276}
Jack Carterd0bd6422013-04-18 00:41:53 +00001277
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001278int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001279
Jack Cartera63b16a2012-09-07 00:23:42 +00001280 if (Name[0] == 'f') {
1281 StringRef NumString = Name.substr(1);
1282 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001283 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001284 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001285 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001286 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001287 return IntVal;
1288 }
1289 return -1;
1290}
Jack Cartera63b16a2012-09-07 00:23:42 +00001291
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001292int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1293
1294 if (Name.startswith("fcc")) {
1295 StringRef NumString = Name.substr(3);
1296 unsigned IntVal;
1297 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001298 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001299 if (IntVal > 7) // There are only 8 fcc registers.
1300 return -1;
1301 return IntVal;
1302 }
1303 return -1;
1304}
1305
1306int MipsAsmParser::matchACRegisterName(StringRef Name) {
1307
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001308 if (Name.startswith("ac")) {
1309 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001310 unsigned IntVal;
1311 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001312 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001313 if (IntVal > 3) // There are only 3 acc registers.
1314 return -1;
1315 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001316 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001317 return -1;
1318}
Jack Carterd0bd6422013-04-18 00:41:53 +00001319
Jack Carter5dc8ac92013-09-25 23:50:44 +00001320int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1321 unsigned IntVal;
1322
1323 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1324 return -1;
1325
1326 if (IntVal > 31)
1327 return -1;
1328
1329 return IntVal;
1330}
1331
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001332int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1333 int CC;
1334
1335 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001336 .Case("msair", 0)
1337 .Case("msacsr", 1)
1338 .Case("msaaccess", 2)
1339 .Case("msasave", 3)
1340 .Case("msamodify", 4)
1341 .Case("msarequest", 5)
1342 .Case("msamap", 6)
1343 .Case("msaunmap", 7)
1344 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001345
1346 return CC;
1347}
1348
Jack Carter0b744b32012-10-04 02:29:46 +00001349bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1350 if (Reg > 31)
1351 return false;
1352
1353 aTReg = Reg;
1354 return true;
1355}
1356
Daniel Sandersd89b1362014-03-24 16:48:01 +00001357int MipsAsmParser::getATReg() {
1358 int AT = Options.getATRegNum();
1359 if (AT == 0)
1360 TokError("Pseudo instruction requires $at, which is not available");
1361 return AT;
1362}
Jack Carter0b744b32012-10-04 02:29:46 +00001363
Jack Carterd0bd6422013-04-18 00:41:53 +00001364unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001365 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001366}
1367
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001368unsigned MipsAsmParser::getGPR(int RegNo) {
Daniel Sanders5e94e682014-03-27 16:42:17 +00001369 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1370 RegNo);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001371}
1372
Jack Carter873c7242013-01-12 01:03:14 +00001373int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001374 if (RegNum >
Daniel Sanders64cf5a42014-03-27 15:00:44 +00001375 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
Jack Carterb4dbc172012-09-05 23:34:03 +00001376 return -1;
1377
Jack Carter873c7242013-01-12 01:03:14 +00001378 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001379}
1380
Vladimir Medic4c299852013-11-06 11:27:05 +00001381bool
1382MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1383 StringRef Mnemonic) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001384 DEBUG(dbgs() << "ParseOperand\n");
1385
Jack Carter30a59822012-10-04 04:03:53 +00001386 // Check if the current operand has a custom associated parser, if so, try to
1387 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001388 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1389 if (ResTy == MatchOperand_Success)
1390 return false;
1391 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1392 // there was a match, but an error occurred, in which case, just return that
1393 // the operand parsing failed.
1394 if (ResTy == MatchOperand_ParseFail)
1395 return true;
1396
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001397 DEBUG(dbgs() << ".. Generic Parser\n");
1398
Jack Carterb4dbc172012-09-05 23:34:03 +00001399 switch (getLexer().getKind()) {
1400 default:
1401 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1402 return true;
1403 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001404 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001405 SMLoc S = Parser.getTok().getLoc();
Jack Carterb4dbc172012-09-05 23:34:03 +00001406
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001407 // Almost all registers have been parsed by custom parsers. There is only
1408 // one exception to this. $zero (and it's alias $0) will reach this point
1409 // for div, divu, and similar instructions because it is not an operand
1410 // to the instruction definition but an explicit register. Special case
1411 // this situation for now.
1412 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
Jack Carterb4dbc172012-09-05 23:34:03 +00001413 return false;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001414
Jack Carterd0bd6422013-04-18 00:41:53 +00001415 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001416 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001417 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001418 return true;
1419
Jack Carter873c7242013-01-12 01:03:14 +00001420 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001421 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001422 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001423 const MCExpr *Res =
1424 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001425
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001426 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001427 return false;
1428 }
Vladimir Medic4c299852013-11-06 11:27:05 +00001429 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001430 case AsmToken::LParen:
1431 case AsmToken::Minus:
1432 case AsmToken::Plus:
1433 case AsmToken::Integer:
1434 case AsmToken::String: {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001435 DEBUG(dbgs() << ".. generic integer\n");
1436 OperandMatchResultTy ResTy = ParseImm(Operands);
1437 return ResTy != MatchOperand_Success;
Jack Carterb4dbc172012-09-05 23:34:03 +00001438 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001439 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001440 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001441 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001442 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001443 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001444 return true;
1445
Jack Carter873c7242013-01-12 01:03:14 +00001446 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1447
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001448 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterdc1e35d2012-09-06 20:00:02 +00001449 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001450 } // case AsmToken::Percent
1451 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001452 return true;
1453}
1454
Vladimir Medic4c299852013-11-06 11:27:05 +00001455const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001456 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001457 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001458 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001459 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Sasa Stankovic06c47802014-04-03 10:37:45 +00001460 // It's a constant, evaluate reloc value.
1461 int16_t Val;
1462 switch (getVariantKind(RelocStr)) {
1463 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1464 // Get the 1st 16-bits.
1465 Val = MCE->getValue() & 0xffff;
1466 break;
1467 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1468 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1469 // 16 bits being negative.
1470 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1471 break;
1472 case MCSymbolRefExpr::VK_Mips_HIGHER:
1473 // Get the 3rd 16-bits.
1474 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1475 break;
1476 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1477 // Get the 4th 16-bits.
1478 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1479 break;
1480 default:
1481 report_fatal_error("Unsupported reloc value!");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001482 }
Sasa Stankovic06c47802014-04-03 10:37:45 +00001483 return MCConstantExpr::Create(Val, getContext());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001484 }
1485
Jack Carterb5cf5902013-04-17 00:18:04 +00001486 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001487 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001488 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001489 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001490 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001491 return Res;
1492 }
1493
1494 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001495 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1496
Sasa Stankovic06c47802014-04-03 10:37:45 +00001497 // Try to create target expression.
1498 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1499 return MipsMCExpr::Create(VK, Expr, getContext());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001500
Jack Carterd0bd6422013-04-18 00:41:53 +00001501 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1502 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001503 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1504 return Res;
1505 }
1506
1507 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001508 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1509 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1510 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001511 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001512 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001513 return Expr;
1514}
1515
1516bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1517
1518 switch (Expr->getKind()) {
1519 case MCExpr::Constant:
1520 return true;
1521 case MCExpr::SymbolRef:
1522 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1523 case MCExpr::Binary:
1524 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1525 if (!isEvaluated(BE->getLHS()))
1526 return false;
1527 return isEvaluated(BE->getRHS());
1528 }
1529 case MCExpr::Unary:
1530 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001531 case MCExpr::Target:
1532 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001533 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001534 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001535}
Jack Carterd0bd6422013-04-18 00:41:53 +00001536
Jack Carterb5cf5902013-04-17 00:18:04 +00001537bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001538 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001539 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001540 if (Tok.isNot(AsmToken::Identifier))
1541 return true;
1542
1543 std::string Str = Tok.getIdentifier().str();
1544
Jack Carterd0bd6422013-04-18 00:41:53 +00001545 Parser.Lex(); // Eat the identifier.
1546 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001547 const MCExpr *IdVal;
1548 SMLoc EndLoc;
1549
1550 if (getLexer().getKind() == AsmToken::LParen) {
1551 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001552 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001553 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001554 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001555 const AsmToken &nextTok = Parser.getTok();
1556 if (nextTok.isNot(AsmToken::Identifier))
1557 return true;
1558 Str += "(%";
1559 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001560 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001561 if (getLexer().getKind() != AsmToken::LParen)
1562 return true;
1563 } else
1564 break;
1565 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001566 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001567 return true;
1568
1569 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001570 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001571
1572 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001573 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001574
Jack Carterd0bd6422013-04-18 00:41:53 +00001575 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001576 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001577}
1578
Jack Carterb4dbc172012-09-05 23:34:03 +00001579bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1580 SMLoc &EndLoc) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001581 SmallVector<MCParsedAsmOperand *, 1> Operands;
1582 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1583 if (ResTy == MatchOperand_Success) {
1584 assert(Operands.size() == 1);
1585 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
1586 StartLoc = Operand.getStartLoc();
1587 EndLoc = Operand.getEndLoc();
1588
1589 // AFAIK, we only support numeric registers and named GPR's in CFI
1590 // directives.
1591 // Don't worry about eating tokens before failing. Using an unrecognised
1592 // register is a parse error.
1593 if (Operand.isGPRAsmReg()) {
1594 // Resolve to GPR32 or GPR64 appropriately.
1595 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1596 }
1597
NAKAMURA Takumibd524ef2014-04-15 14:06:27 +00001598 delete &Operand;
1599
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001600 return (RegNo == (unsigned)-1);
1601 }
1602
1603 assert(Operands.size() == 0);
Vladimir Medic4c299852013-11-06 11:27:05 +00001604 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001605}
1606
Jack Carterb5cf5902013-04-17 00:18:04 +00001607bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001608 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001609 bool Result = true;
1610
1611 while (getLexer().getKind() == AsmToken::LParen)
1612 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001613
Jack Carterd0bd6422013-04-18 00:41:53 +00001614 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001615 default:
1616 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001617 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001618 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001619 case AsmToken::Integer:
1620 case AsmToken::Minus:
1621 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001622 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001623 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001624 else
1625 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001626 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001627 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001628 break;
Jack Carter873c7242013-01-12 01:03:14 +00001629 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001630 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001631 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001632 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001633}
1634
Jack Carterb4dbc172012-09-05 23:34:03 +00001635MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001636 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001637 DEBUG(dbgs() << "parseMemOperand\n");
Craig Topper062a2ba2014-04-25 05:30:21 +00001638 const MCExpr *IdVal = nullptr;
Jack Carter873c7242013-01-12 01:03:14 +00001639 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001640 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001641 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001642 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001643 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001644
Jack Carterb5cf5902013-04-17 00:18:04 +00001645 if (getLexer().getKind() == AsmToken::LParen) {
1646 Parser.Lex();
1647 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001648 }
1649
Jack Carterb5cf5902013-04-17 00:18:04 +00001650 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001651 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001652 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001653
Jack Carterd0bd6422013-04-18 00:41:53 +00001654 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001655 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001656 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001657 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001658 SMLoc E =
1659 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001660 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001661 return MatchOperand_Success;
1662 }
1663 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001664 SMLoc E =
1665 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001666
Jack Carterd0bd6422013-04-18 00:41:53 +00001667 // Zero register assumed, add a memory operand with ZERO as its base.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001668 // "Base" will be managed by k_Memory.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001669 MipsOperand *Base = MipsOperand::CreateGPRReg(
1670 0, getContext().getRegisterInfo(), S, E, *this);
1671 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001672 return MatchOperand_Success;
1673 }
1674 Error(Parser.getTok().getLoc(), "'(' expected");
1675 return MatchOperand_ParseFail;
1676 }
1677
Jack Carterd0bd6422013-04-18 00:41:53 +00001678 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001679 }
1680
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001681 Res = ParseAnyRegister(Operands);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001682 if (Res != MatchOperand_Success)
1683 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001684
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001685 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001686 Error(Parser.getTok().getLoc(), "')' expected");
1687 return MatchOperand_ParseFail;
1688 }
1689
Jack Carter873c7242013-01-12 01:03:14 +00001690 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1691
Jack Carterd0bd6422013-04-18 00:41:53 +00001692 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001693
Craig Topper062a2ba2014-04-25 05:30:21 +00001694 if (!IdVal)
Jack Carterdc1e35d2012-09-06 20:00:02 +00001695 IdVal = MCConstantExpr::Create(0, getContext());
1696
Jack Carterd0bd6422013-04-18 00:41:53 +00001697 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001698 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterd0bd6422013-04-18 00:41:53 +00001699 // Remove the register from the operands.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001700 // "op" will be managed by k_Memory.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001701 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001702 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001703 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1704 int64_t Imm;
1705 if (IdVal->EvaluateAsAbsolute(Imm))
1706 IdVal = MCConstantExpr::Create(Imm, getContext());
1707 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1708 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1709 getContext());
1710 }
1711
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001712 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001713 return MatchOperand_Success;
1714}
1715
Daniel Sanderse34a1202014-03-31 18:51:43 +00001716bool MipsAsmParser::searchSymbolAlias(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001717 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001718
Jack Carterd76b2372013-03-21 21:44:16 +00001719 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1720 if (Sym) {
1721 SMLoc S = Parser.getTok().getLoc();
1722 const MCExpr *Expr;
1723 if (Sym->isVariable())
1724 Expr = Sym->getVariableValue();
1725 else
1726 return false;
1727 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001728 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00001729 const StringRef DefSymbol = Ref->getSymbol().getName();
1730 if (DefSymbol.startswith("$")) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001731 OperandMatchResultTy ResTy =
1732 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
Daniel Sanders09934572014-04-01 10:37:46 +00001733 if (ResTy == MatchOperand_Success) {
1734 Parser.Lex();
Jack Carterd76b2372013-03-21 21:44:16 +00001735 return true;
Daniel Sanders09934572014-04-01 10:37:46 +00001736 } else if (ResTy == MatchOperand_ParseFail)
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001737 llvm_unreachable("Should never ParseFail");
1738 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001739 }
1740 } else if (Expr->getKind() == MCExpr::Constant) {
1741 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00001742 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1743 MipsOperand *op =
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001744 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
Jack Carterd76b2372013-03-21 21:44:16 +00001745 Operands.push_back(op);
1746 return true;
1747 }
1748 }
1749 return false;
1750}
Jack Carterd0bd6422013-04-18 00:41:53 +00001751
Jack Carter873c7242013-01-12 01:03:14 +00001752MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001753MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
1754 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
1755 SMLoc S) {
1756 int Index = matchCPURegisterName(Identifier);
1757 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001758 Operands.push_back(MipsOperand::CreateGPRReg(
1759 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1760 return MatchOperand_Success;
1761 }
1762
1763 Index = matchFPURegisterName(Identifier);
1764 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001765 Operands.push_back(MipsOperand::CreateFGRReg(
1766 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1767 return MatchOperand_Success;
1768 }
1769
1770 Index = matchFCCRegisterName(Identifier);
1771 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001772 Operands.push_back(MipsOperand::CreateFCCReg(
1773 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1774 return MatchOperand_Success;
1775 }
1776
1777 Index = matchACRegisterName(Identifier);
1778 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001779 Operands.push_back(MipsOperand::CreateACCReg(
1780 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1781 return MatchOperand_Success;
1782 }
1783
1784 Index = matchMSA128RegisterName(Identifier);
1785 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001786 Operands.push_back(MipsOperand::CreateMSA128Reg(
1787 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1788 return MatchOperand_Success;
1789 }
1790
1791 Index = matchMSA128CtrlRegisterName(Identifier);
1792 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001793 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1794 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1795 return MatchOperand_Success;
1796 }
1797
1798 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001799}
1800
1801MipsAsmParser::OperandMatchResultTy
Daniel Sanders21bce302014-04-01 12:35:23 +00001802MipsAsmParser::MatchAnyRegisterWithoutDollar(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001803 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
Daniel Sanders315386c2014-04-01 10:40:14 +00001804 auto Token = Parser.getLexer().peekTok(false);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001805
1806 if (Token.is(AsmToken::Identifier)) {
1807 DEBUG(dbgs() << ".. identifier\n");
1808 StringRef Identifier = Token.getIdentifier();
Daniel Sanders09934572014-04-01 10:37:46 +00001809 OperandMatchResultTy ResTy =
1810 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
Daniel Sanders09934572014-04-01 10:37:46 +00001811 return ResTy;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001812 } else if (Token.is(AsmToken::Integer)) {
1813 DEBUG(dbgs() << ".. integer\n");
1814 Operands.push_back(MipsOperand::CreateNumericReg(
1815 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
1816 *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001817 return MatchOperand_Success;
1818 }
1819
1820 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
1821
1822 return MatchOperand_NoMatch;
1823}
1824
1825MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
1826 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1827 DEBUG(dbgs() << "ParseAnyRegister\n");
1828
1829 auto Token = Parser.getTok();
1830
1831 SMLoc S = Token.getLoc();
1832
1833 if (Token.isNot(AsmToken::Dollar)) {
1834 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
1835 if (Token.is(AsmToken::Identifier)) {
1836 if (searchSymbolAlias(Operands))
1837 return MatchOperand_Success;
1838 }
1839 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
1840 return MatchOperand_NoMatch;
1841 }
1842 DEBUG(dbgs() << ".. $\n");
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001843
Daniel Sanders21bce302014-04-01 12:35:23 +00001844 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
Daniel Sanders315386c2014-04-01 10:40:14 +00001845 if (ResTy == MatchOperand_Success) {
1846 Parser.Lex(); // $
1847 Parser.Lex(); // identifier
1848 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001849 return ResTy;
1850}
1851
1852MipsAsmParser::OperandMatchResultTy
1853MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1854 switch (getLexer().getKind()) {
1855 default:
1856 return MatchOperand_NoMatch;
1857 case AsmToken::LParen:
1858 case AsmToken::Minus:
1859 case AsmToken::Plus:
1860 case AsmToken::Integer:
1861 case AsmToken::String:
1862 break;
1863 }
1864
1865 const MCExpr *IdVal;
1866 SMLoc S = Parser.getTok().getLoc();
1867 if (getParser().parseExpression(IdVal))
1868 return MatchOperand_ParseFail;
1869
1870 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1871 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1872 return MatchOperand_Success;
1873}
1874
1875MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
1876 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1877 DEBUG(dbgs() << "ParseJumpTarget\n");
1878
1879 SMLoc S = getLexer().getLoc();
1880
1881 // Integers and expressions are acceptable
1882 OperandMatchResultTy ResTy = ParseImm(Operands);
1883 if (ResTy != MatchOperand_NoMatch)
1884 return ResTy;
1885
Daniel Sanders315386c2014-04-01 10:40:14 +00001886 // Registers are a valid target and have priority over symbols.
1887 ResTy = ParseAnyRegister(Operands);
1888 if (ResTy != MatchOperand_NoMatch)
1889 return ResTy;
1890
Daniel Sandersffd84362014-04-01 10:41:48 +00001891 const MCExpr *Expr = nullptr;
1892 if (Parser.parseExpression(Expr)) {
1893 // We have no way of knowing if a symbol was consumed so we must ParseFail
1894 return MatchOperand_ParseFail;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001895 }
Daniel Sandersffd84362014-04-01 10:41:48 +00001896 Operands.push_back(
1897 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001898 return MatchOperand_Success;
Jack Carter873c7242013-01-12 01:03:14 +00001899}
1900
Vladimir Medic2b953d02013-10-01 09:48:56 +00001901MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001902MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00001903 const MCExpr *IdVal;
1904 // If the first token is '$' we may have register operand.
1905 if (Parser.getTok().is(AsmToken::Dollar))
1906 return MatchOperand_NoMatch;
1907 SMLoc S = Parser.getTok().getLoc();
1908 if (getParser().parseExpression(IdVal))
1909 return MatchOperand_ParseFail;
1910 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00001911 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00001912 int64_t Val = MCE->getValue();
1913 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1914 Operands.push_back(MipsOperand::CreateImm(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001915 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
Vladimir Medic2b953d02013-10-01 09:48:56 +00001916 return MatchOperand_Success;
1917}
1918
Matheus Almeida779c5932013-11-18 12:32:49 +00001919MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001920MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Matheus Almeida779c5932013-11-18 12:32:49 +00001921 switch (getLexer().getKind()) {
1922 default:
1923 return MatchOperand_NoMatch;
1924 case AsmToken::LParen:
1925 case AsmToken::Plus:
1926 case AsmToken::Minus:
1927 case AsmToken::Integer:
1928 break;
1929 }
1930
1931 const MCExpr *Expr;
1932 SMLoc S = Parser.getTok().getLoc();
1933
1934 if (getParser().parseExpression(Expr))
1935 return MatchOperand_ParseFail;
1936
1937 int64_t Val;
1938 if (!Expr->EvaluateAsAbsolute(Val)) {
1939 Error(S, "expected immediate value");
1940 return MatchOperand_ParseFail;
1941 }
1942
1943 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
1944 // and because the CPU always adds one to the immediate field, the allowed
1945 // range becomes 1..4. We'll only check the range here and will deal
1946 // with the addition/subtraction when actually decoding/encoding
1947 // the instruction.
1948 if (Val < 1 || Val > 4) {
1949 Error(S, "immediate not in range (1..4)");
1950 return MatchOperand_ParseFail;
1951 }
1952
Jack Carter3b2c96e2014-01-22 23:31:38 +00001953 Operands.push_back(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001954 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
Matheus Almeida779c5932013-11-18 12:32:49 +00001955 return MatchOperand_Success;
1956}
1957
Jack Carterdc1e35d2012-09-06 20:00:02 +00001958MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1959
Vladimir Medic4c299852013-11-06 11:27:05 +00001960 MCSymbolRefExpr::VariantKind VK =
1961 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1962 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1963 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1964 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1965 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1966 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1967 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1968 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1969 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1970 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1971 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1972 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1973 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1974 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1975 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1976 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1977 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1978 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
Daniel Sandersa567da52014-03-31 15:15:02 +00001979 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
1980 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
1981 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
1982 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
1983 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
1984 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
Zoran Jovanovicb355e8f2014-05-27 14:58:51 +00001985 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
1986 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
Vladimir Medic4c299852013-11-06 11:27:05 +00001987 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001988
Matheus Almeida2852af82014-04-22 10:15:54 +00001989 assert(VK != MCSymbolRefExpr::VK_None);
Daniel Sandersa567da52014-03-31 15:15:02 +00001990
Jack Carterdc1e35d2012-09-06 20:00:02 +00001991 return VK;
1992}
Jack Cartera63b16a2012-09-07 00:23:42 +00001993
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001994/// Sometimes (i.e. load/stores) the operand may be followed immediately by
1995/// either this.
1996/// ::= '(', register, ')'
1997/// handle it before we iterate so we don't get tripped up by the lack of
1998/// a comma.
1999bool MipsAsmParser::ParseParenSuffix(
2000 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2001 if (getLexer().is(AsmToken::LParen)) {
2002 Operands.push_back(
2003 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2004 Parser.Lex();
2005 if (ParseOperand(Operands, Name)) {
2006 SMLoc Loc = getLexer().getLoc();
2007 Parser.eatToEndOfStatement();
2008 return Error(Loc, "unexpected token in argument list");
2009 }
2010 if (Parser.getTok().isNot(AsmToken::RParen)) {
2011 SMLoc Loc = getLexer().getLoc();
2012 Parser.eatToEndOfStatement();
2013 return Error(Loc, "unexpected token, expected ')'");
2014 }
2015 Operands.push_back(
2016 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2017 Parser.Lex();
2018 }
2019 return false;
2020}
2021
2022/// Sometimes (i.e. in MSA) the operand may be followed immediately by
2023/// either one of these.
2024/// ::= '[', register, ']'
2025/// ::= '[', integer, ']'
2026/// handle it before we iterate so we don't get tripped up by the lack of
2027/// a comma.
2028bool MipsAsmParser::ParseBracketSuffix(
2029 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2030 if (getLexer().is(AsmToken::LBrac)) {
2031 Operands.push_back(
2032 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2033 Parser.Lex();
2034 if (ParseOperand(Operands, Name)) {
2035 SMLoc Loc = getLexer().getLoc();
2036 Parser.eatToEndOfStatement();
2037 return Error(Loc, "unexpected token in argument list");
2038 }
2039 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2040 SMLoc Loc = getLexer().getLoc();
2041 Parser.eatToEndOfStatement();
2042 return Error(Loc, "unexpected token, expected ']'");
2043 }
2044 Operands.push_back(
2045 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2046 Parser.Lex();
2047 }
2048 return false;
2049}
2050
Vladimir Medic4c299852013-11-06 11:27:05 +00002051bool MipsAsmParser::ParseInstruction(
2052 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2053 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002054 DEBUG(dbgs() << "ParseInstruction\n");
Vladimir Medic74593e62013-07-17 15:00:42 +00002055 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002056 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002057 Parser.eatToEndOfStatement();
2058 return Error(NameLoc, "Unknown instruction");
2059 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002060 // First operand in MCInst is instruction mnemonic.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002061 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00002062
2063 // Read the remaining operands.
2064 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2065 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002066 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002067 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002068 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002069 return Error(Loc, "unexpected token in argument list");
2070 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002071 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2072 return true;
2073 // AFAIK, parenthesis suffixes are never on the first operand
Jack Carterb4dbc172012-09-05 23:34:03 +00002074
Jack Carterd0bd6422013-04-18 00:41:53 +00002075 while (getLexer().is(AsmToken::Comma)) {
2076 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002077 // Parse and remember the operand.
2078 if (ParseOperand(Operands, Name)) {
2079 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002080 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002081 return Error(Loc, "unexpected token in argument list");
2082 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002083 // Parse bracket and parenthesis suffixes before we iterate
2084 if (getLexer().is(AsmToken::LBrac)) {
2085 if (ParseBracketSuffix(Name, Operands))
2086 return true;
2087 } else if (getLexer().is(AsmToken::LParen) &&
2088 ParseParenSuffix(Name, Operands))
2089 return true;
Jack Carterb4dbc172012-09-05 23:34:03 +00002090 }
2091 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002092 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2093 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002094 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002095 return Error(Loc, "unexpected token in argument list");
2096 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002097 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002098 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002099}
2100
Jack Carter0b744b32012-10-04 02:29:46 +00002101bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002102 SMLoc Loc = getLexer().getLoc();
2103 Parser.eatToEndOfStatement();
2104 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002105}
2106
Matheus Almeida525bc4f2014-04-30 11:28:42 +00002107bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) {
2108 return Error(Loc, ErrorMsg);
2109}
2110
Jack Carter0b744b32012-10-04 02:29:46 +00002111bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002112 // Line should look like: ".set noat".
2113 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002114 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002115 // eat noat
2116 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002117 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2119 reportParseError("unexpected token in statement");
2120 return false;
2121 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002122 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002123 return false;
2124}
Jack Carterd0bd6422013-04-18 00:41:53 +00002125
Jack Carter0b744b32012-10-04 02:29:46 +00002126bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002127 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002128 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002129 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002130 getParser().Lex();
2131 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002132 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002133 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002134 return false;
2135 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002136 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002137 if (getLexer().isNot(AsmToken::Dollar)) {
2138 reportParseError("unexpected token in statement");
2139 return false;
2140 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002141 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002142 const AsmToken &Reg = Parser.getTok();
2143 if (Reg.is(AsmToken::Identifier)) {
2144 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2145 } else if (Reg.is(AsmToken::Integer)) {
2146 AtRegNo = Reg.getIntVal();
2147 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002148 reportParseError("unexpected token in statement");
2149 return false;
2150 }
Jack Carter1ac53222013-02-20 23:11:17 +00002151
Daniel Sanders71a89d922014-03-25 13:01:06 +00002152 if (AtRegNo < 0 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002153 reportParseError("unexpected token in statement");
2154 return false;
2155 }
2156
2157 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002158 reportParseError("unexpected token in statement");
2159 return false;
2160 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002161 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002162
2163 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2164 reportParseError("unexpected token in statement");
2165 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002166 }
2167 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002168 return false;
2169 } else {
2170 reportParseError("unexpected token in statement");
2171 return false;
2172 }
2173}
2174
2175bool MipsAsmParser::parseSetReorderDirective() {
2176 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002177 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002178 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2179 reportParseError("unexpected token in statement");
2180 return false;
2181 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002182 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002183 getTargetStreamer().emitDirectiveSetReorder();
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::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002189 Parser.Lex();
2190 // If this is not the end of the statement, report an error.
2191 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2192 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002193 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002194 }
2195 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002196 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002197 Parser.Lex(); // Consume the EndOfStatement.
2198 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002199}
2200
2201bool MipsAsmParser::parseSetMacroDirective() {
2202 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002203 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002204 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2205 reportParseError("unexpected token in statement");
2206 return false;
2207 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002208 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002209 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002210 return false;
2211}
2212
2213bool MipsAsmParser::parseSetNoMacroDirective() {
2214 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002215 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002216 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2217 reportParseError("`noreorder' must be set before `nomacro'");
2218 return false;
2219 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002220 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002221 reportParseError("`noreorder' must be set before `nomacro'");
2222 return false;
2223 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002224 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002225 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002226 return false;
2227}
Jack Carterd76b2372013-03-21 21:44:16 +00002228
Jack Carter39536722014-01-22 23:08:42 +00002229bool MipsAsmParser::parseSetNoMips16Directive() {
2230 Parser.Lex();
2231 // If this is not the end of the statement, report an error.
2232 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2233 reportParseError("unexpected token in statement");
2234 return false;
2235 }
2236 // For now do nothing.
2237 Parser.Lex(); // Consume the EndOfStatement.
2238 return false;
2239}
2240
Jack Carterd76b2372013-03-21 21:44:16 +00002241bool MipsAsmParser::parseSetAssignment() {
2242 StringRef Name;
2243 const MCExpr *Value;
2244
2245 if (Parser.parseIdentifier(Name))
2246 reportParseError("expected identifier after .set");
2247
2248 if (getLexer().isNot(AsmToken::Comma))
2249 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002250 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002251
Jack Carter3b2c96e2014-01-22 23:31:38 +00002252 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002253 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002254
Jack Carterd0bd6422013-04-18 00:41:53 +00002255 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002256 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002257 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002258 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002259 Sym = getContext().GetOrCreateSymbol(Name);
2260 Sym->setVariableValue(Value);
2261
2262 return false;
2263}
Jack Carterd0bd6422013-04-18 00:41:53 +00002264
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002265bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2266 Parser.Lex();
2267 if (getLexer().isNot(AsmToken::EndOfStatement))
2268 return reportParseError("unexpected token in .set directive");
2269
Matheus Almeida2852af82014-04-22 10:15:54 +00002270 switch (Feature) {
2271 default:
2272 llvm_unreachable("Unimplemented feature");
2273 case Mips::FeatureDSP:
2274 setFeatureBits(Mips::FeatureDSP, "dsp");
2275 getTargetStreamer().emitDirectiveSetDsp();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002276 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002277 case Mips::FeatureMicroMips:
2278 getTargetStreamer().emitDirectiveSetMicroMips();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002279 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002280 case Mips::FeatureMips16:
2281 getTargetStreamer().emitDirectiveSetMips16();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002282 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002283 case Mips::FeatureMips32r2:
2284 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2285 getTargetStreamer().emitDirectiveSetMips32R2();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002286 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002287 case Mips::FeatureMips64:
2288 setFeatureBits(Mips::FeatureMips64, "mips64");
2289 getTargetStreamer().emitDirectiveSetMips64();
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002290 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002291 case Mips::FeatureMips64r2:
2292 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2293 getTargetStreamer().emitDirectiveSetMips64R2();
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002294 break;
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002295 }
2296 return false;
2297}
2298
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002299bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2300 if (!getLexer().is(AsmToken::Dollar))
2301 return false;
2302
2303 Parser.Lex();
2304
2305 const AsmToken &Reg = Parser.getTok();
2306 if (Reg.is(AsmToken::Identifier)) {
2307 RegNum = matchCPURegisterName(Reg.getIdentifier());
2308 } else if (Reg.is(AsmToken::Integer)) {
2309 RegNum = Reg.getIntVal();
2310 } else {
2311 return false;
2312 }
2313
2314 Parser.Lex();
2315 return true;
2316}
2317
2318bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2319 if (getLexer().isNot(AsmToken::Comma)) {
2320 SMLoc Loc = getLexer().getLoc();
2321 Parser.eatToEndOfStatement();
2322 return Error(Loc, ErrorStr);
2323 }
2324
Matheus Almeida2852af82014-04-22 10:15:54 +00002325 Parser.Lex(); // Eat the comma.
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002326 return true;
2327}
2328
Matheus Almeida525bc4f2014-04-30 11:28:42 +00002329bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2330 if (Options.isReorder())
2331 Warning(Loc, ".cpload in reorder section");
2332
2333 // FIXME: Warn if cpload is used in Mips16 mode.
2334
2335 SmallVector<MCParsedAsmOperand *, 1> Reg;
2336 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2337 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2338 reportParseError("expected register containing function address");
2339 return false;
2340 }
2341
2342 MipsOperand *RegOpnd = static_cast<MipsOperand *>(Reg[0]);
2343 if (!RegOpnd->isGPRAsmReg()) {
2344 reportParseError(RegOpnd->getStartLoc(), "invalid register");
2345 return false;
2346 }
2347
2348 getTargetStreamer().emitDirectiveCpload(RegOpnd->getGPR32Reg());
2349 delete RegOpnd;
2350 return false;
2351}
2352
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002353bool MipsAsmParser::parseDirectiveCPSetup() {
2354 unsigned FuncReg;
2355 unsigned Save;
2356 bool SaveIsReg = true;
2357
2358 if (!parseRegister(FuncReg))
2359 return reportParseError("expected register containing function address");
2360 FuncReg = getGPR(FuncReg);
2361
2362 if (!eatComma("expected comma parsing directive"))
2363 return true;
2364
2365 if (!parseRegister(Save)) {
2366 const AsmToken &Tok = Parser.getTok();
2367 if (Tok.is(AsmToken::Integer)) {
2368 Save = Tok.getIntVal();
2369 SaveIsReg = false;
2370 Parser.Lex();
2371 } else
2372 return reportParseError("expected save register or stack offset");
2373 } else
2374 Save = getGPR(Save);
2375
2376 if (!eatComma("expected comma parsing directive"))
2377 return true;
2378
2379 StringRef Name;
2380 if (Parser.parseIdentifier(Name))
2381 reportParseError("expected identifier");
2382 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002383
Matheus Almeidad92a3fa2014-05-01 10:24:46 +00002384 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002385 return false;
2386}
2387
Matheus Almeida0051f2d2014-04-16 15:48:55 +00002388bool MipsAsmParser::parseDirectiveNaN() {
2389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2390 const AsmToken &Tok = Parser.getTok();
2391
2392 if (Tok.getString() == "2008") {
2393 Parser.Lex();
2394 getTargetStreamer().emitDirectiveNaN2008();
2395 return false;
2396 } else if (Tok.getString() == "legacy") {
2397 Parser.Lex();
2398 getTargetStreamer().emitDirectiveNaNLegacy();
2399 return false;
2400 }
2401 }
2402 // If we don't recognize the option passed to the .nan
2403 // directive (e.g. no option or unknown option), emit an error.
2404 reportParseError("invalid option in .nan directive");
2405 return false;
2406}
2407
Jack Carter0b744b32012-10-04 02:29:46 +00002408bool MipsAsmParser::parseDirectiveSet() {
2409
Jack Carterd0bd6422013-04-18 00:41:53 +00002410 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002411 const AsmToken &Tok = Parser.getTok();
2412
2413 if (Tok.getString() == "noat") {
2414 return parseSetNoAtDirective();
2415 } else if (Tok.getString() == "at") {
2416 return parseSetAtDirective();
2417 } else if (Tok.getString() == "reorder") {
2418 return parseSetReorderDirective();
2419 } else if (Tok.getString() == "noreorder") {
2420 return parseSetNoReorderDirective();
2421 } else if (Tok.getString() == "macro") {
2422 return parseSetMacroDirective();
2423 } else if (Tok.getString() == "nomacro") {
2424 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002425 } else if (Tok.getString() == "mips16") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002426 return parseSetFeature(Mips::FeatureMips16);
Jack Carter0b744b32012-10-04 02:29:46 +00002427 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002428 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002429 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002430 getTargetStreamer().emitDirectiveSetNoMicroMips();
2431 Parser.eatToEndOfStatement();
2432 return false;
2433 } else if (Tok.getString() == "micromips") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002434 return parseSetFeature(Mips::FeatureMicroMips);
Vladimir Medic615b26e2014-03-04 09:54:09 +00002435 } else if (Tok.getString() == "mips32r2") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002436 return parseSetFeature(Mips::FeatureMips32r2);
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002437 } else if (Tok.getString() == "mips64") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002438 return parseSetFeature(Mips::FeatureMips64);
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002439 } else if (Tok.getString() == "mips64r2") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002440 return parseSetFeature(Mips::FeatureMips64r2);
Vladimir Medic27c398e2014-03-05 11:05:09 +00002441 } else if (Tok.getString() == "dsp") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002442 return parseSetFeature(Mips::FeatureDSP);
Jack Carterd76b2372013-03-21 21:44:16 +00002443 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002444 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002445 parseSetAssignment();
2446 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002447 }
Jack Carter07c818d2013-01-25 01:31:34 +00002448
Jack Carter0b744b32012-10-04 02:29:46 +00002449 return true;
2450}
2451
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002452/// parseDataDirective
Jack Carter07c818d2013-01-25 01:31:34 +00002453/// ::= .word [ expression (, expression)* ]
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002454bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
Jack Carter07c818d2013-01-25 01:31:34 +00002455 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2456 for (;;) {
2457 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002458 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002459 return true;
2460
2461 getParser().getStreamer().EmitValue(Value, Size);
2462
2463 if (getLexer().is(AsmToken::EndOfStatement))
2464 break;
2465
2466 // FIXME: Improve diagnostic.
2467 if (getLexer().isNot(AsmToken::Comma))
2468 return Error(L, "unexpected token in directive");
2469 Parser.Lex();
2470 }
2471 }
2472
2473 Parser.Lex();
2474 return false;
2475}
2476
Vladimir Medic4c299852013-11-06 11:27:05 +00002477/// parseDirectiveGpWord
2478/// ::= .gpword local_sym
2479bool MipsAsmParser::parseDirectiveGpWord() {
2480 const MCExpr *Value;
2481 // EmitGPRel32Value requires an expression, so we are using base class
2482 // method to evaluate the expression.
2483 if (getParser().parseExpression(Value))
2484 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002485 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002486
Vladimir Medice10c1122013-11-13 13:18:04 +00002487 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002488 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002489 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002490 return false;
2491}
2492
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002493/// parseDirectiveGpDWord
Rafael Espindolab59fb732014-03-28 18:50:26 +00002494/// ::= .gpdword local_sym
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002495bool MipsAsmParser::parseDirectiveGpDWord() {
Rafael Espindolab59fb732014-03-28 18:50:26 +00002496 const MCExpr *Value;
2497 // EmitGPRel64Value requires an expression, so we are using base class
2498 // method to evaluate the expression.
2499 if (getParser().parseExpression(Value))
2500 return true;
2501 getParser().getStreamer().EmitGPRel64Value(Value);
2502
2503 if (getLexer().isNot(AsmToken::EndOfStatement))
2504 return Error(getLexer().getLoc(), "unexpected token in directive");
2505 Parser.Lex(); // Eat EndOfStatement token.
2506 return false;
2507}
2508
Jack Carter0cd3c192014-01-06 23:27:31 +00002509bool MipsAsmParser::parseDirectiveOption() {
2510 // Get the option token.
2511 AsmToken Tok = Parser.getTok();
2512 // At the moment only identifiers are supported.
2513 if (Tok.isNot(AsmToken::Identifier)) {
2514 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2515 Parser.eatToEndOfStatement();
2516 return false;
2517 }
2518
2519 StringRef Option = Tok.getIdentifier();
2520
2521 if (Option == "pic0") {
2522 getTargetStreamer().emitDirectiveOptionPic0();
2523 Parser.Lex();
2524 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2525 Error(Parser.getTok().getLoc(),
2526 "unexpected token in .option pic0 directive");
2527 Parser.eatToEndOfStatement();
2528 }
2529 return false;
2530 }
2531
Matheus Almeidaf79b2812014-03-26 13:40:29 +00002532 if (Option == "pic2") {
2533 getTargetStreamer().emitDirectiveOptionPic2();
2534 Parser.Lex();
2535 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2536 Error(Parser.getTok().getLoc(),
2537 "unexpected token in .option pic2 directive");
2538 Parser.eatToEndOfStatement();
2539 }
2540 return false;
2541 }
2542
Jack Carter0cd3c192014-01-06 23:27:31 +00002543 // Unknown option.
2544 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2545 Parser.eatToEndOfStatement();
2546 return false;
2547}
2548
Jack Carter0b744b32012-10-04 02:29:46 +00002549bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002550 StringRef IDVal = DirectiveID.getString();
2551
Matheus Almeida525bc4f2014-04-30 11:28:42 +00002552 if (IDVal == ".cpload")
2553 return parseDirectiveCPLoad(DirectiveID.getLoc());
Matheus Almeidaab5633b2014-03-26 15:44:18 +00002554 if (IDVal == ".dword") {
2555 parseDataDirective(8, DirectiveID.getLoc());
2556 return false;
2557 }
2558
Jack Carterd0bd6422013-04-18 00:41:53 +00002559 if (IDVal == ".ent") {
2560 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002561 Parser.Lex();
2562 return false;
2563 }
2564
Jack Carter07c818d2013-01-25 01:31:34 +00002565 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002566 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002567 Parser.Lex();
2568 return false;
2569 }
2570
Jack Carter07c818d2013-01-25 01:31:34 +00002571 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002572 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002573 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002574 return false;
2575 }
2576
Jack Carter07c818d2013-01-25 01:31:34 +00002577 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002578 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002579 }
2580
Jack Carter07c818d2013-01-25 01:31:34 +00002581 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002582 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002583 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002584 return false;
2585 }
2586
Jack Carter07c818d2013-01-25 01:31:34 +00002587 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002588 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002589 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002590 return false;
2591 }
2592
Matheus Almeida0051f2d2014-04-16 15:48:55 +00002593 if (IDVal == ".nan")
2594 return parseDirectiveNaN();
2595
Jack Carter07c818d2013-01-25 01:31:34 +00002596 if (IDVal == ".gpword") {
Vladimir Medic4c299852013-11-06 11:27:05 +00002597 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002598 return false;
2599 }
2600
Rafael Espindolab59fb732014-03-28 18:50:26 +00002601 if (IDVal == ".gpdword") {
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002602 parseDirectiveGpDWord();
Rafael Espindolab59fb732014-03-28 18:50:26 +00002603 return false;
2604 }
2605
Jack Carter07c818d2013-01-25 01:31:34 +00002606 if (IDVal == ".word") {
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002607 parseDataDirective(4, DirectiveID.getLoc());
Jack Carter07c818d2013-01-25 01:31:34 +00002608 return false;
2609 }
2610
Jack Carter0cd3c192014-01-06 23:27:31 +00002611 if (IDVal == ".option")
2612 return parseDirectiveOption();
2613
2614 if (IDVal == ".abicalls") {
2615 getTargetStreamer().emitDirectiveAbiCalls();
2616 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2617 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2618 // Clear line
2619 Parser.eatToEndOfStatement();
2620 }
2621 return false;
2622 }
2623
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002624 if (IDVal == ".cpsetup")
2625 return parseDirectiveCPSetup();
2626
Rafael Espindola870c4e92012-01-11 03:56:41 +00002627 return true;
2628}
2629
Rafael Espindola870c4e92012-01-11 03:56:41 +00002630extern "C" void LLVMInitializeMipsAsmParser() {
2631 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2632 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2633 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2634 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2635}
Jack Carterb4dbc172012-09-05 23:34:03 +00002636
2637#define GET_REGISTER_MATCHER
2638#define GET_MATCHER_IMPLEMENTATION
2639#include "MipsGenAsmMatcher.inc"