blob: d8e783e92c45233ccfa2190a5edcd43626a1fbb1 [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
275
276 /// Potentially any (e.g. $1)
277 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
278 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
279 RegKind_CCR | RegKind_HWRegs
Jack Carter873c7242013-01-12 01:03:14 +0000280 };
281
282private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000283 enum KindTy {
Daniel Sanders21bce302014-04-01 12:35:23 +0000284 k_Immediate, /// An immediate (possibly involving symbol references)
285 k_Memory, /// Base + Offset Memory Address
286 k_PhysRegister, /// A physical register from the Mips namespace
287 k_RegisterIndex, /// A register index in one or more RegKind.
288 k_Token /// A simple token
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000289 } Kind;
290
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000291 MipsOperand(KindTy K, MipsAsmParser &Parser)
292 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
293
294 /// For diagnostics, and checking the assembler temporary
295 MipsAsmParser &AsmParser;
Jack Carterb4dbc172012-09-05 23:34:03 +0000296
Eric Christopher8996c5d2013-03-15 00:42:55 +0000297 struct Token {
298 const char *Data;
299 unsigned Length;
300 };
301
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000302 struct PhysRegOp {
303 unsigned Num; /// Register Number
304 };
305
306 struct RegIdxOp {
307 unsigned Index; /// Index into the register class
308 RegKind Kind; /// Bitfield of the kinds it could possibly be
309 const MCRegisterInfo *RegInfo;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000310 };
311
312 struct ImmOp {
313 const MCExpr *Val;
314 };
315
316 struct MemOp {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000317 MipsOperand *Base;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000318 const MCExpr *Off;
319 };
320
Jack Carterb4dbc172012-09-05 23:34:03 +0000321 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000322 struct Token Tok;
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000323 struct PhysRegOp PhysReg;
324 struct RegIdxOp RegIdx;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000325 struct ImmOp Imm;
326 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000327 };
328
329 SMLoc StartLoc, EndLoc;
330
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000331 /// Internal constructor for register kinds
332 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
333 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
334 MipsAsmParser &Parser) {
335 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
336 Op->RegIdx.Index = Index;
337 Op->RegIdx.RegInfo = RegInfo;
338 Op->RegIdx.Kind = RegKind;
339 Op->StartLoc = S;
340 Op->EndLoc = E;
341 return Op;
342 }
343
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000344public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000345 /// Coerce the register to GPR32 and return the real register for the current
346 /// target.
347 unsigned getGPR32Reg() const {
348 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
349 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
350 unsigned ClassID = Mips::GPR32RegClassID;
351 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000352 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000353
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000354 /// Coerce the register to GPR64 and return the real register for the current
355 /// target.
356 unsigned getGPR64Reg() const {
357 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
358 unsigned ClassID = Mips::GPR64RegClassID;
359 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000360 }
361
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000362private:
363 /// Coerce the register to AFGR64 and return the real register for the current
364 /// target.
365 unsigned getAFGR64Reg() const {
366 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
367 if (RegIdx.Index % 2 != 0)
368 AsmParser.Warning(StartLoc, "Float register should be even.");
369 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
370 .getRegister(RegIdx.Index / 2);
371 }
372
373 /// Coerce the register to FGR64 and return the real register for the current
374 /// target.
375 unsigned getFGR64Reg() const {
376 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
377 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
378 .getRegister(RegIdx.Index);
379 }
380
381 /// Coerce the register to FGR32 and return the real register for the current
382 /// target.
383 unsigned getFGR32Reg() const {
384 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
385 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
386 .getRegister(RegIdx.Index);
387 }
388
389 /// Coerce the register to FGRH32 and return the real register for the current
390 /// target.
391 unsigned getFGRH32Reg() const {
392 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
393 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
394 .getRegister(RegIdx.Index);
395 }
396
397 /// Coerce the register to FCC and return the real register for the current
398 /// target.
399 unsigned getFCCReg() const {
400 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
401 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
402 .getRegister(RegIdx.Index);
403 }
404
405 /// Coerce the register to MSA128 and return the real register for the current
406 /// target.
407 unsigned getMSA128Reg() const {
408 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
409 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
410 // identical
411 unsigned ClassID = Mips::MSA128BRegClassID;
412 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
413 }
414
415 /// Coerce the register to MSACtrl and return the real register for the
416 /// current target.
417 unsigned getMSACtrlReg() const {
418 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
419 unsigned ClassID = Mips::MSACtrlRegClassID;
420 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
421 }
422
423 /// Coerce the register to COP2 and return the real register for the
424 /// current target.
425 unsigned getCOP2Reg() const {
426 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
427 unsigned ClassID = Mips::COP2RegClassID;
428 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
429 }
430
431 /// Coerce the register to ACC64DSP and return the real register for the
432 /// current target.
433 unsigned getACC64DSPReg() const {
434 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
435 unsigned ClassID = Mips::ACC64DSPRegClassID;
436 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
437 }
438
439 /// Coerce the register to HI32DSP and return the real register for the
440 /// current target.
441 unsigned getHI32DSPReg() const {
442 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
443 unsigned ClassID = Mips::HI32DSPRegClassID;
444 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
445 }
446
447 /// Coerce the register to LO32DSP and return the real register for the
448 /// current target.
449 unsigned getLO32DSPReg() const {
450 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
451 unsigned ClassID = Mips::LO32DSPRegClassID;
452 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
453 }
454
455 /// Coerce the register to CCR and return the real register for the
456 /// current target.
457 unsigned getCCRReg() const {
458 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
459 unsigned ClassID = Mips::CCRRegClassID;
460 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
461 }
462
463 /// Coerce the register to HWRegs and return the real register for the
464 /// current target.
465 unsigned getHWRegsReg() const {
466 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
467 unsigned ClassID = Mips::HWRegsRegClassID;
468 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
469 }
470
471public:
Vladimir Medic4c299852013-11-06 11:27:05 +0000472 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000473 // Add as immediate when possible. Null MCExpr = 0.
Craig Topper062a2ba2014-04-25 05:30:21 +0000474 if (!Expr)
Jack Carterb4dbc172012-09-05 23:34:03 +0000475 Inst.addOperand(MCOperand::CreateImm(0));
476 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
477 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
478 else
479 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000480 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000481
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000482 void addRegOperands(MCInst &Inst, unsigned N) const {
483 llvm_unreachable("Use a custom parser instead");
484 }
485
Daniel Sanders21bce302014-04-01 12:35:23 +0000486 /// Render the operand to an MCInst as a GPR32
487 /// Asserts if the wrong number of operands are requested, or the operand
488 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000489 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
490 assert(N == 1 && "Invalid number of operands!");
491 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
492 }
493
Daniel Sanders21bce302014-04-01 12:35:23 +0000494 /// Render the operand to an MCInst as a GPR64
495 /// Asserts if the wrong number of operands are requested, or the operand
496 /// is not a k_RegisterIndex compatible with RegKind_GPR
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000497 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
498 assert(N == 1 && "Invalid number of operands!");
499 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
500 }
501
502 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
503 assert(N == 1 && "Invalid number of operands!");
504 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
505 }
506
507 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
508 assert(N == 1 && "Invalid number of operands!");
509 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
510 }
511
512 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
513 assert(N == 1 && "Invalid number of operands!");
514 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
515 }
516
517 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
518 assert(N == 1 && "Invalid number of operands!");
519 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
520 }
521
522 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
523 assert(N == 1 && "Invalid number of operands!");
524 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
525 }
526
527 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
528 assert(N == 1 && "Invalid number of operands!");
529 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
530 }
531
532 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
533 assert(N == 1 && "Invalid number of operands!");
534 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
535 }
536
537 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
538 assert(N == 1 && "Invalid number of operands!");
539 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
540 }
541
542 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
543 assert(N == 1 && "Invalid number of operands!");
544 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
545 }
546
547 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
548 assert(N == 1 && "Invalid number of operands!");
549 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
550 }
551
552 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
553 assert(N == 1 && "Invalid number of operands!");
554 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
555 }
556
557 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
558 assert(N == 1 && "Invalid number of operands!");
559 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
560 }
561
562 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
563 assert(N == 1 && "Invalid number of operands!");
564 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
565 }
566
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000567 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000568 assert(N == 1 && "Invalid number of operands!");
569 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000570 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000571 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000572
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000573 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000574 assert(N == 2 && "Invalid number of operands!");
575
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000576 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
Jack Carterdc1e35d2012-09-06 20:00:02 +0000577
578 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000579 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000580 }
581
Craig Topper56c590a2014-04-29 07:58:02 +0000582 bool isReg() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000583 // As a special case until we sort out the definition of div/divu, pretend
584 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
585 if (isGPRAsmReg() && RegIdx.Index == 0)
586 return true;
587
588 return Kind == k_PhysRegister;
589 }
590 bool isRegIdx() const { return Kind == k_RegisterIndex; }
Craig Topper56c590a2014-04-29 07:58:02 +0000591 bool isImm() const override { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000592 bool isConstantImm() const {
593 return isImm() && dyn_cast<MCConstantExpr>(getImm());
594 }
Craig Topper56c590a2014-04-29 07:58:02 +0000595 bool isToken() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000596 // Note: It's not possible to pretend that other operand kinds are tokens.
597 // The matcher emitter checks tokens first.
598 return Kind == k_Token;
599 }
Craig Topper56c590a2014-04-29 07:58:02 +0000600 bool isMem() const override { return Kind == k_Memory; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000601 bool isInvNum() const { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000602 bool isLSAImm() const {
603 if (!isConstantImm())
604 return false;
605 int64_t Val = getConstantImm();
606 return 1 <= Val && Val <= 4;
607 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000608
609 StringRef getToken() const {
610 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000611 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000612 }
613
Craig Topper56c590a2014-04-29 07:58:02 +0000614 unsigned getReg() const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000615 // As a special case until we sort out the definition of div/divu, pretend
616 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
617 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
618 RegIdx.Kind & RegKind_GPR)
619 return getGPR32Reg(); // FIXME: GPR64 too
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000620
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000621 assert(Kind == k_PhysRegister && "Invalid access!");
622 return PhysReg.Num;
Jack Carter873c7242013-01-12 01:03:14 +0000623 }
624
Jack Carterb4dbc172012-09-05 23:34:03 +0000625 const MCExpr *getImm() const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000626 assert((Kind == k_Immediate) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000627 return Imm.Val;
628 }
629
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000630 int64_t getConstantImm() const {
631 const MCExpr *Val = getImm();
632 return static_cast<const MCConstantExpr *>(Val)->getValue();
633 }
634
635 MipsOperand *getMemBase() const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000636 assert((Kind == k_Memory) && "Invalid access!");
637 return Mem.Base;
638 }
639
640 const MCExpr *getMemOff() const {
641 assert((Kind == k_Memory) && "Invalid access!");
642 return Mem.Off;
643 }
644
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000645 static MipsOperand *CreateToken(StringRef Str, SMLoc S,
646 MipsAsmParser &Parser) {
647 MipsOperand *Op = new MipsOperand(k_Token, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000648 Op->Tok.Data = Str.data();
649 Op->Tok.Length = Str.size();
650 Op->StartLoc = S;
651 Op->EndLoc = S;
652 return Op;
653 }
654
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000655 /// Create a numeric register (e.g. $1). The exact register remains
656 /// unresolved until an instruction successfully matches
657 static MipsOperand *CreateNumericReg(unsigned Index,
658 const MCRegisterInfo *RegInfo, SMLoc S,
659 SMLoc E, MipsAsmParser &Parser) {
660 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
661 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000662 }
663
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000664 /// Create a register that is definitely a GPR.
665 /// This is typically only used for named registers such as $gp.
666 static MipsOperand *CreateGPRReg(unsigned Index,
667 const MCRegisterInfo *RegInfo, SMLoc S,
668 SMLoc E, MipsAsmParser &Parser) {
669 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000670 }
671
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000672 /// Create a register that is definitely a FGR.
673 /// This is typically only used for named registers such as $f0.
674 static MipsOperand *CreateFGRReg(unsigned Index,
675 const MCRegisterInfo *RegInfo, SMLoc S,
676 SMLoc E, MipsAsmParser &Parser) {
677 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
678 }
679
680 /// Create a register that is definitely an FCC.
681 /// This is typically only used for named registers such as $fcc0.
682 static MipsOperand *CreateFCCReg(unsigned Index,
683 const MCRegisterInfo *RegInfo, SMLoc S,
684 SMLoc E, MipsAsmParser &Parser) {
685 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
686 }
687
688 /// Create a register that is definitely an ACC.
689 /// This is typically only used for named registers such as $ac0.
690 static MipsOperand *CreateACCReg(unsigned Index,
691 const MCRegisterInfo *RegInfo, SMLoc S,
692 SMLoc E, MipsAsmParser &Parser) {
693 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
694 }
695
696 /// Create a register that is definitely an MSA128.
697 /// This is typically only used for named registers such as $w0.
698 static MipsOperand *CreateMSA128Reg(unsigned Index,
699 const MCRegisterInfo *RegInfo, SMLoc S,
700 SMLoc E, MipsAsmParser &Parser) {
701 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
702 }
703
704 /// Create a register that is definitely an MSACtrl.
705 /// This is typically only used for named registers such as $msaaccess.
706 static MipsOperand *CreateMSACtrlReg(unsigned Index,
707 const MCRegisterInfo *RegInfo, SMLoc S,
708 SMLoc E, MipsAsmParser &Parser) {
709 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
710 }
711
712 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
713 MipsAsmParser &Parser) {
714 MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000715 Op->Imm.Val = Val;
716 Op->StartLoc = S;
717 Op->EndLoc = E;
718 return Op;
719 }
720
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000721 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
722 SMLoc E, MipsAsmParser &Parser) {
723 MipsOperand *Op = new MipsOperand(k_Memory, Parser);
Jack Carterdc1e35d2012-09-06 20:00:02 +0000724 Op->Mem.Base = Base;
725 Op->Mem.Off = Off;
726 Op->StartLoc = S;
727 Op->EndLoc = E;
728 return Op;
729 }
730
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000731 bool isGPRAsmReg() const {
732 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000733 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000734 bool isFGRAsmReg() const {
735 // AFGR64 is $0-$15 but we handle this in getAFGR64()
736 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000737 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000738 bool isHWRegsAsmReg() const {
739 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000740 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000741 bool isCCRAsmReg() const {
742 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000743 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000744 bool isFCCAsmReg() const {
745 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
Jack Carter873c7242013-01-12 01:03:14 +0000746 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000747 bool isACCAsmReg() const {
748 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
Vladimir Medic233dd512013-06-24 10:05:34 +0000749 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000750 bool isCOP2AsmReg() const {
751 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000752 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000753 bool isMSA128AsmReg() const {
754 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000755 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000756 bool isMSACtrlAsmReg() const {
757 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000758 }
759
Jack Carterb4dbc172012-09-05 23:34:03 +0000760 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper56c590a2014-04-29 07:58:02 +0000761 SMLoc getStartLoc() const override { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000762 /// getEndLoc - Get the location of the last token of this operand.
Craig Topper56c590a2014-04-29 07:58:02 +0000763 SMLoc getEndLoc() const override { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000764
NAKAMURA Takumie1f35832014-04-15 14:13:21 +0000765 virtual ~MipsOperand() {
766 switch (Kind) {
767 case k_Immediate:
768 break;
769 case k_Memory:
770 delete Mem.Base;
771 break;
772 case k_PhysRegister:
773 case k_RegisterIndex:
774 case k_Token:
775 break;
776 }
777 }
778
Craig Topper56c590a2014-04-29 07:58:02 +0000779 void print(raw_ostream &OS) const override {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000780 switch (Kind) {
781 case k_Immediate:
782 OS << "Imm<";
783 Imm.Val->print(OS);
784 OS << ">";
785 break;
786 case k_Memory:
787 OS << "Mem<";
788 Mem.Base->print(OS);
789 OS << ", ";
790 Mem.Off->print(OS);
791 OS << ">";
792 break;
793 case k_PhysRegister:
794 OS << "PhysReg<" << PhysReg.Num << ">";
795 break;
796 case k_RegisterIndex:
797 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
798 break;
799 case k_Token:
800 OS << Tok.Data;
801 break;
802 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000803 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000804}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000805} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000806
Jack Carter9e65aa32013-03-22 00:05:30 +0000807namespace llvm {
808extern const MCInstrDesc MipsInsts[];
809}
810static const MCInstrDesc &getInstDesc(unsigned Opcode) {
811 return MipsInsts[Opcode];
812}
813
814bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000815 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000816 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000817
Jack Carter9e65aa32013-03-22 00:05:30 +0000818 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000819
820 if (MCID.isBranch() || MCID.isCall()) {
821 const unsigned Opcode = Inst.getOpcode();
822 MCOperand Offset;
823
824 switch (Opcode) {
825 default:
826 break;
827 case Mips::BEQ:
828 case Mips::BNE:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000829 case Mips::BEQ_MM:
830 case Mips::BNE_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000831 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000832 Offset = Inst.getOperand(2);
833 if (!Offset.isImm())
834 break; // We'll deal with this situation later on when applying fixups.
835 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
836 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000837 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000838 return Error(IDLoc, "branch to misaligned address");
839 break;
840 case Mips::BGEZ:
841 case Mips::BGTZ:
842 case Mips::BLEZ:
843 case Mips::BLTZ:
844 case Mips::BGEZAL:
845 case Mips::BLTZAL:
846 case Mips::BC1F:
847 case Mips::BC1T:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000848 case Mips::BGEZ_MM:
849 case Mips::BGTZ_MM:
850 case Mips::BLEZ_MM:
851 case Mips::BLTZ_MM:
852 case Mips::BGEZAL_MM:
853 case Mips::BLTZAL_MM:
854 case Mips::BC1F_MM:
855 case Mips::BC1T_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000856 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000857 Offset = Inst.getOperand(1);
858 if (!Offset.isImm())
859 break; // We'll deal with this situation later on when applying fixups.
860 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
861 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000862 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000863 return Error(IDLoc, "branch to misaligned address");
864 break;
865 }
866 }
867
Jack Carterc15c1d22013-04-25 23:31:35 +0000868 if (MCID.hasDelaySlot() && Options.isReorder()) {
869 // If this instruction has a delay slot and .set reorder is active,
870 // emit a NOP after it.
871 Instructions.push_back(Inst);
872 MCInst NopInst;
873 NopInst.setOpcode(Mips::SLL);
874 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
875 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
876 NopInst.addOperand(MCOperand::CreateImm(0));
877 Instructions.push_back(NopInst);
878 return false;
879 }
880
Jack Carter9e65aa32013-03-22 00:05:30 +0000881 if (MCID.mayLoad() || MCID.mayStore()) {
882 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000883 // reference or immediate we may have to expand instructions.
884 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000885 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000886 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
887 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000888 MCOperand &Op = Inst.getOperand(i);
889 if (Op.isImm()) {
890 int MemOffset = Op.getImm();
891 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000892 // Offset can't exceed 16bit value.
893 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000894 return false;
895 }
896 } else if (Op.isExpr()) {
897 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000898 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000899 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000900 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000901 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000902 // Expand symbol.
903 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000904 return false;
905 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000906 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000908 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000909 }
910 }
911 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000912 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000913 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000914
915 if (needsExpansion(Inst))
916 expandInstruction(Inst, IDLoc, Instructions);
917 else
918 Instructions.push_back(Inst);
919
920 return false;
921}
922
Jack Carter30a59822012-10-04 04:03:53 +0000923bool MipsAsmParser::needsExpansion(MCInst &Inst) {
924
Jack Carterd0bd6422013-04-18 00:41:53 +0000925 switch (Inst.getOpcode()) {
926 case Mips::LoadImm32Reg:
927 case Mips::LoadAddr32Imm:
928 case Mips::LoadAddr32Reg:
929 return true;
930 default:
931 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000932 }
933}
Jack Carter92995f12012-10-06 00:53:28 +0000934
Jack Carter30a59822012-10-04 04:03:53 +0000935void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000936 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000937 switch (Inst.getOpcode()) {
938 case Mips::LoadImm32Reg:
939 return expandLoadImm(Inst, IDLoc, Instructions);
940 case Mips::LoadAddr32Imm:
941 return expandLoadAddressImm(Inst, IDLoc, Instructions);
942 case Mips::LoadAddr32Reg:
943 return expandLoadAddressReg(Inst, IDLoc, Instructions);
944 }
Jack Carter30a59822012-10-04 04:03:53 +0000945}
Jack Carter92995f12012-10-06 00:53:28 +0000946
Jack Carter30a59822012-10-04 04:03:53 +0000947void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000948 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000949 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000950 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000951 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000952 const MCOperand &RegOp = Inst.getOperand(0);
953 assert(RegOp.isReg() && "expected register operand kind");
954
955 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000956 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000957 if (0 <= ImmValue && ImmValue <= 65535) {
958 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000959 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000960 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000961 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000962 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000963 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000964 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000965 } else if (ImmValue < 0 && ImmValue >= -32768) {
966 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000967 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000968 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000969 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000970 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000971 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000972 Instructions.push_back(tmpInst);
973 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000974 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000975 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000976 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000977 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000978 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
979 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000980 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000981 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000982 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000983 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
984 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
985 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
986 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000987 Instructions.push_back(tmpInst);
988 }
989}
Jack Carter92995f12012-10-06 00:53:28 +0000990
Vladimir Medic4c299852013-11-06 11:27:05 +0000991void
992MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
993 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000994 MCInst tmpInst;
995 const MCOperand &ImmOp = Inst.getOperand(2);
996 assert(ImmOp.isImm() && "expected immediate operand kind");
997 const MCOperand &SrcRegOp = Inst.getOperand(1);
998 assert(SrcRegOp.isReg() && "expected register operand kind");
999 const MCOperand &DstRegOp = Inst.getOperand(0);
1000 assert(DstRegOp.isReg() && "expected register operand kind");
1001 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001002 if (-32768 <= ImmValue && ImmValue <= 65535) {
1003 // For -32768 <= j <= 65535.
1004 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +00001005 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +00001006 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1007 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1008 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1009 Instructions.push_back(tmpInst);
1010 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001011 // For any other value of j that is representable as a 32-bit integer.
1012 // la d,j(s) => lui d,hi16(j)
1013 // ori d,d,lo16(j)
1014 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +00001015 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001016 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1017 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1018 Instructions.push_back(tmpInst);
1019 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001020 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001021 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1022 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1023 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1024 Instructions.push_back(tmpInst);
1025 tmpInst.clear();
1026 tmpInst.setOpcode(Mips::ADDu);
1027 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1028 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1029 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1030 Instructions.push_back(tmpInst);
1031 }
1032}
1033
Vladimir Medic4c299852013-11-06 11:27:05 +00001034void
1035MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1036 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +00001037 MCInst tmpInst;
1038 const MCOperand &ImmOp = Inst.getOperand(1);
1039 assert(ImmOp.isImm() && "expected immediate operand kind");
1040 const MCOperand &RegOp = Inst.getOperand(0);
1041 assert(RegOp.isReg() && "expected register operand kind");
1042 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001043 if (-32768 <= ImmValue && ImmValue <= 65535) {
1044 // For -32768 <= j <= 65535.
1045 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +00001046 tmpInst.setOpcode(Mips::ADDiu);
1047 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +00001048 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +00001049 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1050 Instructions.push_back(tmpInst);
1051 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001052 // For any other value of j that is representable as a 32-bit integer.
1053 // la d,j => lui d,hi16(j)
1054 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +00001055 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001056 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1057 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1058 Instructions.push_back(tmpInst);
1059 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001060 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001061 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1062 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1063 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1064 Instructions.push_back(tmpInst);
1065 }
1066}
1067
Jack Carter9e65aa32013-03-22 00:05:30 +00001068void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +00001069 SmallVectorImpl<MCInst> &Instructions,
1070 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +00001071 const MCSymbolRefExpr *SR;
1072 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +00001073 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +00001074 const MCExpr *ExprOffset;
1075 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +00001076 unsigned AtRegNum = getReg(
Daniel Sanders5e94e682014-03-27 16:42:17 +00001077 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +00001078 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001079 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1080 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001081 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001082 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1083 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001084 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +00001085 if (isImmOpnd) {
1086 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1087 ImmOffset = Inst.getOperand(2).getImm();
1088 LoOffset = ImmOffset & 0x0000ffff;
1089 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +00001090 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +00001091 if (LoOffset & 0x8000)
1092 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +00001093 } else
Jack Carter9e65aa32013-03-22 00:05:30 +00001094 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +00001095 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +00001096 TempInst.setLoc(IDLoc);
1097 // 1st instruction in expansion is LUi. For load instruction we can use
1098 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +00001099 // but for stores we must use $at.
1100 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +00001101 TempInst.setOpcode(Mips::LUi);
1102 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1103 if (isImmOpnd)
1104 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1105 else {
1106 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001107 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +00001108 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1109 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1110 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001111 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001112 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001113 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +00001114 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001115 }
1116 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001117 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +00001118 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +00001119 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +00001120 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +00001121 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001122 TempInst.setOpcode(Mips::ADDu);
1123 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1124 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1125 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1126 Instructions.push_back(TempInst);
1127 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +00001128 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +00001129 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001130 TempInst.setOpcode(Inst.getOpcode());
1131 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1132 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1133 if (isImmOpnd)
1134 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1135 else {
1136 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001137 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1138 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1139 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001140 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001141 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001142 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +00001143 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001144 }
1145 }
1146 Instructions.push_back(TempInst);
1147 TempInst.clear();
1148}
1149
Vladimir Medic4c299852013-11-06 11:27:05 +00001150bool MipsAsmParser::MatchAndEmitInstruction(
1151 SMLoc IDLoc, unsigned &Opcode,
1152 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
1153 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001154 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +00001155 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +00001156 unsigned MatchResult =
1157 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +00001158
1159 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001160 default:
1161 break;
Jack Carterb4dbc172012-09-05 23:34:03 +00001162 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001163 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +00001164 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +00001165 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +00001166 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +00001167 return false;
1168 }
1169 case Match_MissingFeature:
1170 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1171 return true;
1172 case Match_InvalidOperand: {
1173 SMLoc ErrorLoc = IDLoc;
1174 if (ErrorInfo != ~0U) {
1175 if (ErrorInfo >= Operands.size())
1176 return Error(IDLoc, "too few operands for instruction");
1177
Vladimir Medic4c299852013-11-06 11:27:05 +00001178 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001179 if (ErrorLoc == SMLoc())
1180 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +00001181 }
1182
1183 return Error(ErrorLoc, "invalid operand for instruction");
1184 }
1185 case Match_MnemonicFail:
1186 return Error(IDLoc, "invalid instruction");
1187 }
Rafael Espindola870c4e92012-01-11 03:56:41 +00001188 return true;
1189}
1190
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001191void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1192 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1193 if (RegIndex == 1)
1194 Warning(Loc, "Used $at without \".set noat\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001195 else
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001196 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1197 Twine(RegIndex) + "\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001198 }
1199}
1200
Jack Carter1ac53222013-02-20 23:11:17 +00001201int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001202 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +00001203
Vladimir Medic4c299852013-11-06 11:27:05 +00001204 CC = StringSwitch<unsigned>(Name)
1205 .Case("zero", 0)
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001206 .Case("at", 1)
Vladimir Medic4c299852013-11-06 11:27:05 +00001207 .Case("a0", 4)
1208 .Case("a1", 5)
1209 .Case("a2", 6)
1210 .Case("a3", 7)
1211 .Case("v0", 2)
1212 .Case("v1", 3)
1213 .Case("s0", 16)
1214 .Case("s1", 17)
1215 .Case("s2", 18)
1216 .Case("s3", 19)
1217 .Case("s4", 20)
1218 .Case("s5", 21)
1219 .Case("s6", 22)
1220 .Case("s7", 23)
1221 .Case("k0", 26)
1222 .Case("k1", 27)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001223 .Case("gp", 28)
Vladimir Medic4c299852013-11-06 11:27:05 +00001224 .Case("sp", 29)
1225 .Case("fp", 30)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001226 .Case("s8", 30)
Vladimir Medic4c299852013-11-06 11:27:05 +00001227 .Case("ra", 31)
1228 .Case("t0", 8)
1229 .Case("t1", 9)
1230 .Case("t2", 10)
1231 .Case("t3", 11)
1232 .Case("t4", 12)
1233 .Case("t5", 13)
1234 .Case("t6", 14)
1235 .Case("t7", 15)
1236 .Case("t8", 24)
1237 .Case("t9", 25)
1238 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001239
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001240 if (isN32() || isN64()) {
1241 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1242 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1243 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1244 if (8 <= CC && CC <= 11)
1245 CC += 4;
Jack Carter1ac53222013-02-20 23:11:17 +00001246
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001247 if (CC == -1)
1248 CC = StringSwitch<unsigned>(Name)
1249 .Case("a4", 8)
1250 .Case("a5", 9)
1251 .Case("a6", 10)
1252 .Case("a7", 11)
1253 .Case("kt0", 26)
1254 .Case("kt1", 27)
1255 .Default(-1);
1256 }
Jack Carter1ac53222013-02-20 23:11:17 +00001257
1258 return CC;
1259}
Jack Carterd0bd6422013-04-18 00:41:53 +00001260
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001261int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001262
Jack Cartera63b16a2012-09-07 00:23:42 +00001263 if (Name[0] == 'f') {
1264 StringRef NumString = Name.substr(1);
1265 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001266 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001267 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001268 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001269 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001270 return IntVal;
1271 }
1272 return -1;
1273}
Jack Cartera63b16a2012-09-07 00:23:42 +00001274
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001275int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1276
1277 if (Name.startswith("fcc")) {
1278 StringRef NumString = Name.substr(3);
1279 unsigned IntVal;
1280 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001281 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001282 if (IntVal > 7) // There are only 8 fcc registers.
1283 return -1;
1284 return IntVal;
1285 }
1286 return -1;
1287}
1288
1289int MipsAsmParser::matchACRegisterName(StringRef Name) {
1290
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001291 if (Name.startswith("ac")) {
1292 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001293 unsigned IntVal;
1294 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001295 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001296 if (IntVal > 3) // There are only 3 acc registers.
1297 return -1;
1298 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001299 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001300 return -1;
1301}
Jack Carterd0bd6422013-04-18 00:41:53 +00001302
Jack Carter5dc8ac92013-09-25 23:50:44 +00001303int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1304 unsigned IntVal;
1305
1306 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1307 return -1;
1308
1309 if (IntVal > 31)
1310 return -1;
1311
1312 return IntVal;
1313}
1314
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001315int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1316 int CC;
1317
1318 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001319 .Case("msair", 0)
1320 .Case("msacsr", 1)
1321 .Case("msaaccess", 2)
1322 .Case("msasave", 3)
1323 .Case("msamodify", 4)
1324 .Case("msarequest", 5)
1325 .Case("msamap", 6)
1326 .Case("msaunmap", 7)
1327 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001328
1329 return CC;
1330}
1331
Jack Carter0b744b32012-10-04 02:29:46 +00001332bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1333 if (Reg > 31)
1334 return false;
1335
1336 aTReg = Reg;
1337 return true;
1338}
1339
Daniel Sandersd89b1362014-03-24 16:48:01 +00001340int MipsAsmParser::getATReg() {
1341 int AT = Options.getATRegNum();
1342 if (AT == 0)
1343 TokError("Pseudo instruction requires $at, which is not available");
1344 return AT;
1345}
Jack Carter0b744b32012-10-04 02:29:46 +00001346
Jack Carterd0bd6422013-04-18 00:41:53 +00001347unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001348 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001349}
1350
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001351unsigned MipsAsmParser::getGPR(int RegNo) {
Daniel Sanders5e94e682014-03-27 16:42:17 +00001352 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1353 RegNo);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001354}
1355
Jack Carter873c7242013-01-12 01:03:14 +00001356int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001357 if (RegNum >
Daniel Sanders64cf5a42014-03-27 15:00:44 +00001358 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
Jack Carterb4dbc172012-09-05 23:34:03 +00001359 return -1;
1360
Jack Carter873c7242013-01-12 01:03:14 +00001361 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001362}
1363
Vladimir Medic4c299852013-11-06 11:27:05 +00001364bool
1365MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1366 StringRef Mnemonic) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001367 DEBUG(dbgs() << "ParseOperand\n");
1368
Jack Carter30a59822012-10-04 04:03:53 +00001369 // Check if the current operand has a custom associated parser, if so, try to
1370 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001371 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1372 if (ResTy == MatchOperand_Success)
1373 return false;
1374 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1375 // there was a match, but an error occurred, in which case, just return that
1376 // the operand parsing failed.
1377 if (ResTy == MatchOperand_ParseFail)
1378 return true;
1379
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001380 DEBUG(dbgs() << ".. Generic Parser\n");
1381
Jack Carterb4dbc172012-09-05 23:34:03 +00001382 switch (getLexer().getKind()) {
1383 default:
1384 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1385 return true;
1386 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001387 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001388 SMLoc S = Parser.getTok().getLoc();
Jack Carterb4dbc172012-09-05 23:34:03 +00001389
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001390 // Almost all registers have been parsed by custom parsers. There is only
1391 // one exception to this. $zero (and it's alias $0) will reach this point
1392 // for div, divu, and similar instructions because it is not an operand
1393 // to the instruction definition but an explicit register. Special case
1394 // this situation for now.
1395 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
Jack Carterb4dbc172012-09-05 23:34:03 +00001396 return false;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001397
Jack Carterd0bd6422013-04-18 00:41:53 +00001398 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001399 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001400 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001401 return true;
1402
Jack Carter873c7242013-01-12 01:03:14 +00001403 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001404 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001405 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001406 const MCExpr *Res =
1407 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001408
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001409 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001410 return false;
1411 }
Vladimir Medic4c299852013-11-06 11:27:05 +00001412 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001413 case AsmToken::LParen:
1414 case AsmToken::Minus:
1415 case AsmToken::Plus:
1416 case AsmToken::Integer:
1417 case AsmToken::String: {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001418 DEBUG(dbgs() << ".. generic integer\n");
1419 OperandMatchResultTy ResTy = ParseImm(Operands);
1420 return ResTy != MatchOperand_Success;
Jack Carterb4dbc172012-09-05 23:34:03 +00001421 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001422 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001423 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001424 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001425 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001426 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001427 return true;
1428
Jack Carter873c7242013-01-12 01:03:14 +00001429 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1430
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001431 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterdc1e35d2012-09-06 20:00:02 +00001432 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001433 } // case AsmToken::Percent
1434 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001435 return true;
1436}
1437
Vladimir Medic4c299852013-11-06 11:27:05 +00001438const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001439 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001440 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001441 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001442 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Sasa Stankovic06c47802014-04-03 10:37:45 +00001443 // It's a constant, evaluate reloc value.
1444 int16_t Val;
1445 switch (getVariantKind(RelocStr)) {
1446 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1447 // Get the 1st 16-bits.
1448 Val = MCE->getValue() & 0xffff;
1449 break;
1450 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1451 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1452 // 16 bits being negative.
1453 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1454 break;
1455 case MCSymbolRefExpr::VK_Mips_HIGHER:
1456 // Get the 3rd 16-bits.
1457 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1458 break;
1459 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1460 // Get the 4th 16-bits.
1461 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1462 break;
1463 default:
1464 report_fatal_error("Unsupported reloc value!");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001465 }
Sasa Stankovic06c47802014-04-03 10:37:45 +00001466 return MCConstantExpr::Create(Val, getContext());
Jack Carterdc1e35d2012-09-06 20:00:02 +00001467 }
1468
Jack Carterb5cf5902013-04-17 00:18:04 +00001469 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001470 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001471 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001472 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001473 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001474 return Res;
1475 }
1476
1477 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001478 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1479
Sasa Stankovic06c47802014-04-03 10:37:45 +00001480 // Try to create target expression.
1481 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1482 return MipsMCExpr::Create(VK, Expr, getContext());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001483
Jack Carterd0bd6422013-04-18 00:41:53 +00001484 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1485 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001486 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1487 return Res;
1488 }
1489
1490 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001491 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1492 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1493 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001494 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001495 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001496 return Expr;
1497}
1498
1499bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1500
1501 switch (Expr->getKind()) {
1502 case MCExpr::Constant:
1503 return true;
1504 case MCExpr::SymbolRef:
1505 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1506 case MCExpr::Binary:
1507 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1508 if (!isEvaluated(BE->getLHS()))
1509 return false;
1510 return isEvaluated(BE->getRHS());
1511 }
1512 case MCExpr::Unary:
1513 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001514 case MCExpr::Target:
1515 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001516 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001517 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001518}
Jack Carterd0bd6422013-04-18 00:41:53 +00001519
Jack Carterb5cf5902013-04-17 00:18:04 +00001520bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001521 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001522 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001523 if (Tok.isNot(AsmToken::Identifier))
1524 return true;
1525
1526 std::string Str = Tok.getIdentifier().str();
1527
Jack Carterd0bd6422013-04-18 00:41:53 +00001528 Parser.Lex(); // Eat the identifier.
1529 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001530 const MCExpr *IdVal;
1531 SMLoc EndLoc;
1532
1533 if (getLexer().getKind() == AsmToken::LParen) {
1534 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001535 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001536 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001537 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001538 const AsmToken &nextTok = Parser.getTok();
1539 if (nextTok.isNot(AsmToken::Identifier))
1540 return true;
1541 Str += "(%";
1542 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001543 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001544 if (getLexer().getKind() != AsmToken::LParen)
1545 return true;
1546 } else
1547 break;
1548 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001549 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001550 return true;
1551
1552 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001553 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001554
1555 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001556 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001557
Jack Carterd0bd6422013-04-18 00:41:53 +00001558 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001559 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001560}
1561
Jack Carterb4dbc172012-09-05 23:34:03 +00001562bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1563 SMLoc &EndLoc) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001564 SmallVector<MCParsedAsmOperand *, 1> Operands;
1565 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1566 if (ResTy == MatchOperand_Success) {
1567 assert(Operands.size() == 1);
1568 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
1569 StartLoc = Operand.getStartLoc();
1570 EndLoc = Operand.getEndLoc();
1571
1572 // AFAIK, we only support numeric registers and named GPR's in CFI
1573 // directives.
1574 // Don't worry about eating tokens before failing. Using an unrecognised
1575 // register is a parse error.
1576 if (Operand.isGPRAsmReg()) {
1577 // Resolve to GPR32 or GPR64 appropriately.
1578 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1579 }
1580
NAKAMURA Takumibd524ef2014-04-15 14:06:27 +00001581 delete &Operand;
1582
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001583 return (RegNo == (unsigned)-1);
1584 }
1585
1586 assert(Operands.size() == 0);
Vladimir Medic4c299852013-11-06 11:27:05 +00001587 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001588}
1589
Jack Carterb5cf5902013-04-17 00:18:04 +00001590bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001591 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001592 bool Result = true;
1593
1594 while (getLexer().getKind() == AsmToken::LParen)
1595 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001596
Jack Carterd0bd6422013-04-18 00:41:53 +00001597 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001598 default:
1599 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001600 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001601 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001602 case AsmToken::Integer:
1603 case AsmToken::Minus:
1604 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001605 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001606 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001607 else
1608 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001609 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001610 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001611 break;
Jack Carter873c7242013-01-12 01:03:14 +00001612 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001613 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001614 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001615 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001616}
1617
Jack Carterb4dbc172012-09-05 23:34:03 +00001618MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001619 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001620 DEBUG(dbgs() << "parseMemOperand\n");
Craig Topper062a2ba2014-04-25 05:30:21 +00001621 const MCExpr *IdVal = nullptr;
Jack Carter873c7242013-01-12 01:03:14 +00001622 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001623 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001624 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001625 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001626 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001627
Jack Carterb5cf5902013-04-17 00:18:04 +00001628 if (getLexer().getKind() == AsmToken::LParen) {
1629 Parser.Lex();
1630 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001631 }
1632
Jack Carterb5cf5902013-04-17 00:18:04 +00001633 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001634 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001635 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001636
Jack Carterd0bd6422013-04-18 00:41:53 +00001637 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001638 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001639 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001640 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001641 SMLoc E =
1642 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001643 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001644 return MatchOperand_Success;
1645 }
1646 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001647 SMLoc E =
1648 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001649
Jack Carterd0bd6422013-04-18 00:41:53 +00001650 // Zero register assumed, add a memory operand with ZERO as its base.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001651 // "Base" will be managed by k_Memory.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001652 MipsOperand *Base = MipsOperand::CreateGPRReg(
1653 0, getContext().getRegisterInfo(), S, E, *this);
1654 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001655 return MatchOperand_Success;
1656 }
1657 Error(Parser.getTok().getLoc(), "'(' expected");
1658 return MatchOperand_ParseFail;
1659 }
1660
Jack Carterd0bd6422013-04-18 00:41:53 +00001661 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001662 }
1663
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001664 Res = ParseAnyRegister(Operands);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001665 if (Res != MatchOperand_Success)
1666 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001667
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001668 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001669 Error(Parser.getTok().getLoc(), "')' expected");
1670 return MatchOperand_ParseFail;
1671 }
1672
Jack Carter873c7242013-01-12 01:03:14 +00001673 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1674
Jack Carterd0bd6422013-04-18 00:41:53 +00001675 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001676
Craig Topper062a2ba2014-04-25 05:30:21 +00001677 if (!IdVal)
Jack Carterdc1e35d2012-09-06 20:00:02 +00001678 IdVal = MCConstantExpr::Create(0, getContext());
1679
Jack Carterd0bd6422013-04-18 00:41:53 +00001680 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001681 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterd0bd6422013-04-18 00:41:53 +00001682 // Remove the register from the operands.
NAKAMURA Takumie1f35832014-04-15 14:13:21 +00001683 // "op" will be managed by k_Memory.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001684 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001685 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001686 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1687 int64_t Imm;
1688 if (IdVal->EvaluateAsAbsolute(Imm))
1689 IdVal = MCConstantExpr::Create(Imm, getContext());
1690 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1691 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1692 getContext());
1693 }
1694
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001695 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001696 return MatchOperand_Success;
1697}
1698
Daniel Sanderse34a1202014-03-31 18:51:43 +00001699bool MipsAsmParser::searchSymbolAlias(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001700 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001701
Jack Carterd76b2372013-03-21 21:44:16 +00001702 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1703 if (Sym) {
1704 SMLoc S = Parser.getTok().getLoc();
1705 const MCExpr *Expr;
1706 if (Sym->isVariable())
1707 Expr = Sym->getVariableValue();
1708 else
1709 return false;
1710 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001711 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00001712 const StringRef DefSymbol = Ref->getSymbol().getName();
1713 if (DefSymbol.startswith("$")) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001714 OperandMatchResultTy ResTy =
1715 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
Daniel Sanders09934572014-04-01 10:37:46 +00001716 if (ResTy == MatchOperand_Success) {
1717 Parser.Lex();
Jack Carterd76b2372013-03-21 21:44:16 +00001718 return true;
Daniel Sanders09934572014-04-01 10:37:46 +00001719 } else if (ResTy == MatchOperand_ParseFail)
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001720 llvm_unreachable("Should never ParseFail");
1721 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001722 }
1723 } else if (Expr->getKind() == MCExpr::Constant) {
1724 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00001725 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1726 MipsOperand *op =
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001727 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
Jack Carterd76b2372013-03-21 21:44:16 +00001728 Operands.push_back(op);
1729 return true;
1730 }
1731 }
1732 return false;
1733}
Jack Carterd0bd6422013-04-18 00:41:53 +00001734
Jack Carter873c7242013-01-12 01:03:14 +00001735MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001736MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
1737 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
1738 SMLoc S) {
1739 int Index = matchCPURegisterName(Identifier);
1740 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001741 Operands.push_back(MipsOperand::CreateGPRReg(
1742 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1743 return MatchOperand_Success;
1744 }
1745
1746 Index = matchFPURegisterName(Identifier);
1747 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001748 Operands.push_back(MipsOperand::CreateFGRReg(
1749 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1750 return MatchOperand_Success;
1751 }
1752
1753 Index = matchFCCRegisterName(Identifier);
1754 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001755 Operands.push_back(MipsOperand::CreateFCCReg(
1756 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1757 return MatchOperand_Success;
1758 }
1759
1760 Index = matchACRegisterName(Identifier);
1761 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001762 Operands.push_back(MipsOperand::CreateACCReg(
1763 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1764 return MatchOperand_Success;
1765 }
1766
1767 Index = matchMSA128RegisterName(Identifier);
1768 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001769 Operands.push_back(MipsOperand::CreateMSA128Reg(
1770 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1771 return MatchOperand_Success;
1772 }
1773
1774 Index = matchMSA128CtrlRegisterName(Identifier);
1775 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001776 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1777 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1778 return MatchOperand_Success;
1779 }
1780
1781 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001782}
1783
1784MipsAsmParser::OperandMatchResultTy
Daniel Sanders21bce302014-04-01 12:35:23 +00001785MipsAsmParser::MatchAnyRegisterWithoutDollar(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001786 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
Daniel Sanders315386c2014-04-01 10:40:14 +00001787 auto Token = Parser.getLexer().peekTok(false);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001788
1789 if (Token.is(AsmToken::Identifier)) {
1790 DEBUG(dbgs() << ".. identifier\n");
1791 StringRef Identifier = Token.getIdentifier();
Daniel Sanders09934572014-04-01 10:37:46 +00001792 OperandMatchResultTy ResTy =
1793 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
Daniel Sanders09934572014-04-01 10:37:46 +00001794 return ResTy;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001795 } else if (Token.is(AsmToken::Integer)) {
1796 DEBUG(dbgs() << ".. integer\n");
1797 Operands.push_back(MipsOperand::CreateNumericReg(
1798 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
1799 *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001800 return MatchOperand_Success;
1801 }
1802
1803 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
1804
1805 return MatchOperand_NoMatch;
1806}
1807
1808MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
1809 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1810 DEBUG(dbgs() << "ParseAnyRegister\n");
1811
1812 auto Token = Parser.getTok();
1813
1814 SMLoc S = Token.getLoc();
1815
1816 if (Token.isNot(AsmToken::Dollar)) {
1817 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
1818 if (Token.is(AsmToken::Identifier)) {
1819 if (searchSymbolAlias(Operands))
1820 return MatchOperand_Success;
1821 }
1822 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
1823 return MatchOperand_NoMatch;
1824 }
1825 DEBUG(dbgs() << ".. $\n");
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001826
Daniel Sanders21bce302014-04-01 12:35:23 +00001827 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
Daniel Sanders315386c2014-04-01 10:40:14 +00001828 if (ResTy == MatchOperand_Success) {
1829 Parser.Lex(); // $
1830 Parser.Lex(); // identifier
1831 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001832 return ResTy;
1833}
1834
1835MipsAsmParser::OperandMatchResultTy
1836MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1837 switch (getLexer().getKind()) {
1838 default:
1839 return MatchOperand_NoMatch;
1840 case AsmToken::LParen:
1841 case AsmToken::Minus:
1842 case AsmToken::Plus:
1843 case AsmToken::Integer:
1844 case AsmToken::String:
1845 break;
1846 }
1847
1848 const MCExpr *IdVal;
1849 SMLoc S = Parser.getTok().getLoc();
1850 if (getParser().parseExpression(IdVal))
1851 return MatchOperand_ParseFail;
1852
1853 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1854 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1855 return MatchOperand_Success;
1856}
1857
1858MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
1859 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1860 DEBUG(dbgs() << "ParseJumpTarget\n");
1861
1862 SMLoc S = getLexer().getLoc();
1863
1864 // Integers and expressions are acceptable
1865 OperandMatchResultTy ResTy = ParseImm(Operands);
1866 if (ResTy != MatchOperand_NoMatch)
1867 return ResTy;
1868
Daniel Sanders315386c2014-04-01 10:40:14 +00001869 // Registers are a valid target and have priority over symbols.
1870 ResTy = ParseAnyRegister(Operands);
1871 if (ResTy != MatchOperand_NoMatch)
1872 return ResTy;
1873
Daniel Sandersffd84362014-04-01 10:41:48 +00001874 const MCExpr *Expr = nullptr;
1875 if (Parser.parseExpression(Expr)) {
1876 // We have no way of knowing if a symbol was consumed so we must ParseFail
1877 return MatchOperand_ParseFail;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001878 }
Daniel Sandersffd84362014-04-01 10:41:48 +00001879 Operands.push_back(
1880 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001881 return MatchOperand_Success;
Jack Carter873c7242013-01-12 01:03:14 +00001882}
1883
Vladimir Medic2b953d02013-10-01 09:48:56 +00001884MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001885MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00001886 const MCExpr *IdVal;
1887 // If the first token is '$' we may have register operand.
1888 if (Parser.getTok().is(AsmToken::Dollar))
1889 return MatchOperand_NoMatch;
1890 SMLoc S = Parser.getTok().getLoc();
1891 if (getParser().parseExpression(IdVal))
1892 return MatchOperand_ParseFail;
1893 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00001894 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00001895 int64_t Val = MCE->getValue();
1896 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1897 Operands.push_back(MipsOperand::CreateImm(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001898 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
Vladimir Medic2b953d02013-10-01 09:48:56 +00001899 return MatchOperand_Success;
1900}
1901
Matheus Almeida779c5932013-11-18 12:32:49 +00001902MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001903MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Matheus Almeida779c5932013-11-18 12:32:49 +00001904 switch (getLexer().getKind()) {
1905 default:
1906 return MatchOperand_NoMatch;
1907 case AsmToken::LParen:
1908 case AsmToken::Plus:
1909 case AsmToken::Minus:
1910 case AsmToken::Integer:
1911 break;
1912 }
1913
1914 const MCExpr *Expr;
1915 SMLoc S = Parser.getTok().getLoc();
1916
1917 if (getParser().parseExpression(Expr))
1918 return MatchOperand_ParseFail;
1919
1920 int64_t Val;
1921 if (!Expr->EvaluateAsAbsolute(Val)) {
1922 Error(S, "expected immediate value");
1923 return MatchOperand_ParseFail;
1924 }
1925
1926 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
1927 // and because the CPU always adds one to the immediate field, the allowed
1928 // range becomes 1..4. We'll only check the range here and will deal
1929 // with the addition/subtraction when actually decoding/encoding
1930 // the instruction.
1931 if (Val < 1 || Val > 4) {
1932 Error(S, "immediate not in range (1..4)");
1933 return MatchOperand_ParseFail;
1934 }
1935
Jack Carter3b2c96e2014-01-22 23:31:38 +00001936 Operands.push_back(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001937 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
Matheus Almeida779c5932013-11-18 12:32:49 +00001938 return MatchOperand_Success;
1939}
1940
Jack Carterdc1e35d2012-09-06 20:00:02 +00001941MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1942
Vladimir Medic4c299852013-11-06 11:27:05 +00001943 MCSymbolRefExpr::VariantKind VK =
1944 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1945 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1946 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1947 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1948 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1949 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1950 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1951 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1952 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1953 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1954 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1955 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1956 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1957 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1958 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1959 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1960 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1961 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
Daniel Sandersa567da52014-03-31 15:15:02 +00001962 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
1963 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
1964 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
1965 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
1966 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
1967 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
Vladimir Medic4c299852013-11-06 11:27:05 +00001968 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001969
Matheus Almeida2852af82014-04-22 10:15:54 +00001970 assert(VK != MCSymbolRefExpr::VK_None);
Daniel Sandersa567da52014-03-31 15:15:02 +00001971
Jack Carterdc1e35d2012-09-06 20:00:02 +00001972 return VK;
1973}
Jack Cartera63b16a2012-09-07 00:23:42 +00001974
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001975/// Sometimes (i.e. load/stores) the operand may be followed immediately by
1976/// either this.
1977/// ::= '(', register, ')'
1978/// handle it before we iterate so we don't get tripped up by the lack of
1979/// a comma.
1980bool MipsAsmParser::ParseParenSuffix(
1981 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1982 if (getLexer().is(AsmToken::LParen)) {
1983 Operands.push_back(
1984 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
1985 Parser.Lex();
1986 if (ParseOperand(Operands, Name)) {
1987 SMLoc Loc = getLexer().getLoc();
1988 Parser.eatToEndOfStatement();
1989 return Error(Loc, "unexpected token in argument list");
1990 }
1991 if (Parser.getTok().isNot(AsmToken::RParen)) {
1992 SMLoc Loc = getLexer().getLoc();
1993 Parser.eatToEndOfStatement();
1994 return Error(Loc, "unexpected token, expected ')'");
1995 }
1996 Operands.push_back(
1997 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
1998 Parser.Lex();
1999 }
2000 return false;
2001}
2002
2003/// Sometimes (i.e. in MSA) the operand may be followed immediately by
2004/// either one of these.
2005/// ::= '[', register, ']'
2006/// ::= '[', integer, ']'
2007/// handle it before we iterate so we don't get tripped up by the lack of
2008/// a comma.
2009bool MipsAsmParser::ParseBracketSuffix(
2010 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2011 if (getLexer().is(AsmToken::LBrac)) {
2012 Operands.push_back(
2013 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2014 Parser.Lex();
2015 if (ParseOperand(Operands, Name)) {
2016 SMLoc Loc = getLexer().getLoc();
2017 Parser.eatToEndOfStatement();
2018 return Error(Loc, "unexpected token in argument list");
2019 }
2020 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2021 SMLoc Loc = getLexer().getLoc();
2022 Parser.eatToEndOfStatement();
2023 return Error(Loc, "unexpected token, expected ']'");
2024 }
2025 Operands.push_back(
2026 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2027 Parser.Lex();
2028 }
2029 return false;
2030}
2031
Vladimir Medic4c299852013-11-06 11:27:05 +00002032bool MipsAsmParser::ParseInstruction(
2033 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2034 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002035 DEBUG(dbgs() << "ParseInstruction\n");
Vladimir Medic74593e62013-07-17 15:00:42 +00002036 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002037 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002038 Parser.eatToEndOfStatement();
2039 return Error(NameLoc, "Unknown instruction");
2040 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002041 // First operand in MCInst is instruction mnemonic.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002042 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00002043
2044 // Read the remaining operands.
2045 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2046 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002047 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002048 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002049 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002050 return Error(Loc, "unexpected token in argument list");
2051 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002052 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2053 return true;
2054 // AFAIK, parenthesis suffixes are never on the first operand
Jack Carterb4dbc172012-09-05 23:34:03 +00002055
Jack Carterd0bd6422013-04-18 00:41:53 +00002056 while (getLexer().is(AsmToken::Comma)) {
2057 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002058 // Parse and remember the operand.
2059 if (ParseOperand(Operands, Name)) {
2060 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002061 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002062 return Error(Loc, "unexpected token in argument list");
2063 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002064 // Parse bracket and parenthesis suffixes before we iterate
2065 if (getLexer().is(AsmToken::LBrac)) {
2066 if (ParseBracketSuffix(Name, Operands))
2067 return true;
2068 } else if (getLexer().is(AsmToken::LParen) &&
2069 ParseParenSuffix(Name, Operands))
2070 return true;
Jack Carterb4dbc172012-09-05 23:34:03 +00002071 }
2072 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2074 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002075 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002076 return Error(Loc, "unexpected token in argument list");
2077 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002078 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002079 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002080}
2081
Jack Carter0b744b32012-10-04 02:29:46 +00002082bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002083 SMLoc Loc = getLexer().getLoc();
2084 Parser.eatToEndOfStatement();
2085 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002086}
2087
Matheus Almeida525bc4f2014-04-30 11:28:42 +00002088bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) {
2089 return Error(Loc, ErrorMsg);
2090}
2091
Jack Carter0b744b32012-10-04 02:29:46 +00002092bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002093 // Line should look like: ".set noat".
2094 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002095 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002096 // eat noat
2097 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002098 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002099 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2100 reportParseError("unexpected token in statement");
2101 return false;
2102 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002103 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002104 return false;
2105}
Jack Carterd0bd6422013-04-18 00:41:53 +00002106
Jack Carter0b744b32012-10-04 02:29:46 +00002107bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002108 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002109 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002110 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002111 getParser().Lex();
2112 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002113 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002114 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002115 return false;
2116 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002117 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002118 if (getLexer().isNot(AsmToken::Dollar)) {
2119 reportParseError("unexpected token in statement");
2120 return false;
2121 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002122 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002123 const AsmToken &Reg = Parser.getTok();
2124 if (Reg.is(AsmToken::Identifier)) {
2125 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2126 } else if (Reg.is(AsmToken::Integer)) {
2127 AtRegNo = Reg.getIntVal();
2128 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002129 reportParseError("unexpected token in statement");
2130 return false;
2131 }
Jack Carter1ac53222013-02-20 23:11:17 +00002132
Daniel Sanders71a89d922014-03-25 13:01:06 +00002133 if (AtRegNo < 0 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002134 reportParseError("unexpected token in statement");
2135 return false;
2136 }
2137
2138 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002139 reportParseError("unexpected token in statement");
2140 return false;
2141 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002142 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002143
2144 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2145 reportParseError("unexpected token in statement");
2146 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002147 }
2148 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002149 return false;
2150 } else {
2151 reportParseError("unexpected token in statement");
2152 return false;
2153 }
2154}
2155
2156bool MipsAsmParser::parseSetReorderDirective() {
2157 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002158 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002159 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2160 reportParseError("unexpected token in statement");
2161 return false;
2162 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002163 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002164 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002165 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002166 return false;
2167}
2168
2169bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002170 Parser.Lex();
2171 // If this is not the end of the statement, report an error.
2172 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2173 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002174 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002175 }
2176 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002177 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002178 Parser.Lex(); // Consume the EndOfStatement.
2179 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002180}
2181
2182bool MipsAsmParser::parseSetMacroDirective() {
2183 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002184 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002185 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2186 reportParseError("unexpected token in statement");
2187 return false;
2188 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002189 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002190 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002191 return false;
2192}
2193
2194bool MipsAsmParser::parseSetNoMacroDirective() {
2195 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002196 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002197 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2198 reportParseError("`noreorder' must be set before `nomacro'");
2199 return false;
2200 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002201 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002202 reportParseError("`noreorder' must be set before `nomacro'");
2203 return false;
2204 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002205 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002206 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002207 return false;
2208}
Jack Carterd76b2372013-03-21 21:44:16 +00002209
Jack Carter39536722014-01-22 23:08:42 +00002210bool MipsAsmParser::parseSetNoMips16Directive() {
2211 Parser.Lex();
2212 // If this is not the end of the statement, report an error.
2213 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2214 reportParseError("unexpected token in statement");
2215 return false;
2216 }
2217 // For now do nothing.
2218 Parser.Lex(); // Consume the EndOfStatement.
2219 return false;
2220}
2221
Jack Carterd76b2372013-03-21 21:44:16 +00002222bool MipsAsmParser::parseSetAssignment() {
2223 StringRef Name;
2224 const MCExpr *Value;
2225
2226 if (Parser.parseIdentifier(Name))
2227 reportParseError("expected identifier after .set");
2228
2229 if (getLexer().isNot(AsmToken::Comma))
2230 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002231 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002232
Jack Carter3b2c96e2014-01-22 23:31:38 +00002233 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002234 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002235
Jack Carterd0bd6422013-04-18 00:41:53 +00002236 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002237 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002238 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002239 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002240 Sym = getContext().GetOrCreateSymbol(Name);
2241 Sym->setVariableValue(Value);
2242
2243 return false;
2244}
Jack Carterd0bd6422013-04-18 00:41:53 +00002245
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002246bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2247 Parser.Lex();
2248 if (getLexer().isNot(AsmToken::EndOfStatement))
2249 return reportParseError("unexpected token in .set directive");
2250
Matheus Almeida2852af82014-04-22 10:15:54 +00002251 switch (Feature) {
2252 default:
2253 llvm_unreachable("Unimplemented feature");
2254 case Mips::FeatureDSP:
2255 setFeatureBits(Mips::FeatureDSP, "dsp");
2256 getTargetStreamer().emitDirectiveSetDsp();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002257 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002258 case Mips::FeatureMicroMips:
2259 getTargetStreamer().emitDirectiveSetMicroMips();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002260 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002261 case Mips::FeatureMips16:
2262 getTargetStreamer().emitDirectiveSetMips16();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002263 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002264 case Mips::FeatureMips32r2:
2265 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2266 getTargetStreamer().emitDirectiveSetMips32R2();
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002267 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002268 case Mips::FeatureMips64:
2269 setFeatureBits(Mips::FeatureMips64, "mips64");
2270 getTargetStreamer().emitDirectiveSetMips64();
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002271 break;
Matheus Almeida2852af82014-04-22 10:15:54 +00002272 case Mips::FeatureMips64r2:
2273 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2274 getTargetStreamer().emitDirectiveSetMips64R2();
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002275 break;
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002276 }
2277 return false;
2278}
2279
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002280bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2281 if (!getLexer().is(AsmToken::Dollar))
2282 return false;
2283
2284 Parser.Lex();
2285
2286 const AsmToken &Reg = Parser.getTok();
2287 if (Reg.is(AsmToken::Identifier)) {
2288 RegNum = matchCPURegisterName(Reg.getIdentifier());
2289 } else if (Reg.is(AsmToken::Integer)) {
2290 RegNum = Reg.getIntVal();
2291 } else {
2292 return false;
2293 }
2294
2295 Parser.Lex();
2296 return true;
2297}
2298
2299bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2300 if (getLexer().isNot(AsmToken::Comma)) {
2301 SMLoc Loc = getLexer().getLoc();
2302 Parser.eatToEndOfStatement();
2303 return Error(Loc, ErrorStr);
2304 }
2305
Matheus Almeida2852af82014-04-22 10:15:54 +00002306 Parser.Lex(); // Eat the comma.
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002307 return true;
2308}
2309
Matheus Almeida525bc4f2014-04-30 11:28:42 +00002310bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2311 if (Options.isReorder())
2312 Warning(Loc, ".cpload in reorder section");
2313
2314 // FIXME: Warn if cpload is used in Mips16 mode.
2315
2316 SmallVector<MCParsedAsmOperand *, 1> Reg;
2317 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2318 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2319 reportParseError("expected register containing function address");
2320 return false;
2321 }
2322
2323 MipsOperand *RegOpnd = static_cast<MipsOperand *>(Reg[0]);
2324 if (!RegOpnd->isGPRAsmReg()) {
2325 reportParseError(RegOpnd->getStartLoc(), "invalid register");
2326 return false;
2327 }
2328
2329 getTargetStreamer().emitDirectiveCpload(RegOpnd->getGPR32Reg());
2330 delete RegOpnd;
2331 return false;
2332}
2333
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002334bool MipsAsmParser::parseDirectiveCPSetup() {
2335 unsigned FuncReg;
2336 unsigned Save;
2337 bool SaveIsReg = true;
2338
2339 if (!parseRegister(FuncReg))
2340 return reportParseError("expected register containing function address");
2341 FuncReg = getGPR(FuncReg);
2342
2343 if (!eatComma("expected comma parsing directive"))
2344 return true;
2345
2346 if (!parseRegister(Save)) {
2347 const AsmToken &Tok = Parser.getTok();
2348 if (Tok.is(AsmToken::Integer)) {
2349 Save = Tok.getIntVal();
2350 SaveIsReg = false;
2351 Parser.Lex();
2352 } else
2353 return reportParseError("expected save register or stack offset");
2354 } else
2355 Save = getGPR(Save);
2356
2357 if (!eatComma("expected comma parsing directive"))
2358 return true;
2359
2360 StringRef Name;
2361 if (Parser.parseIdentifier(Name))
2362 reportParseError("expected identifier");
2363 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002364
Matheus Almeidad92a3fa2014-05-01 10:24:46 +00002365 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002366 return false;
2367}
2368
Matheus Almeida0051f2d2014-04-16 15:48:55 +00002369bool MipsAsmParser::parseDirectiveNaN() {
2370 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2371 const AsmToken &Tok = Parser.getTok();
2372
2373 if (Tok.getString() == "2008") {
2374 Parser.Lex();
2375 getTargetStreamer().emitDirectiveNaN2008();
2376 return false;
2377 } else if (Tok.getString() == "legacy") {
2378 Parser.Lex();
2379 getTargetStreamer().emitDirectiveNaNLegacy();
2380 return false;
2381 }
2382 }
2383 // If we don't recognize the option passed to the .nan
2384 // directive (e.g. no option or unknown option), emit an error.
2385 reportParseError("invalid option in .nan directive");
2386 return false;
2387}
2388
Jack Carter0b744b32012-10-04 02:29:46 +00002389bool MipsAsmParser::parseDirectiveSet() {
2390
Jack Carterd0bd6422013-04-18 00:41:53 +00002391 // Get the next token.
Jack Carter0b744b32012-10-04 02:29:46 +00002392 const AsmToken &Tok = Parser.getTok();
2393
2394 if (Tok.getString() == "noat") {
2395 return parseSetNoAtDirective();
2396 } else if (Tok.getString() == "at") {
2397 return parseSetAtDirective();
2398 } else if (Tok.getString() == "reorder") {
2399 return parseSetReorderDirective();
2400 } else if (Tok.getString() == "noreorder") {
2401 return parseSetNoReorderDirective();
2402 } else if (Tok.getString() == "macro") {
2403 return parseSetMacroDirective();
2404 } else if (Tok.getString() == "nomacro") {
2405 return parseSetNoMacroDirective();
Jack Carter39536722014-01-22 23:08:42 +00002406 } else if (Tok.getString() == "mips16") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002407 return parseSetFeature(Mips::FeatureMips16);
Jack Carter0b744b32012-10-04 02:29:46 +00002408 } else if (Tok.getString() == "nomips16") {
Jack Carter39536722014-01-22 23:08:42 +00002409 return parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +00002410 } else if (Tok.getString() == "nomicromips") {
Rafael Espindola6d5f7ce2014-01-14 04:25:13 +00002411 getTargetStreamer().emitDirectiveSetNoMicroMips();
2412 Parser.eatToEndOfStatement();
2413 return false;
2414 } else if (Tok.getString() == "micromips") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002415 return parseSetFeature(Mips::FeatureMicroMips);
Vladimir Medic615b26e2014-03-04 09:54:09 +00002416 } else if (Tok.getString() == "mips32r2") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002417 return parseSetFeature(Mips::FeatureMips32r2);
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002418 } else if (Tok.getString() == "mips64") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002419 return parseSetFeature(Mips::FeatureMips64);
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002420 } else if (Tok.getString() == "mips64r2") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002421 return parseSetFeature(Mips::FeatureMips64r2);
Vladimir Medic27c398e2014-03-05 11:05:09 +00002422 } else if (Tok.getString() == "dsp") {
Matheus Almeida2852af82014-04-22 10:15:54 +00002423 return parseSetFeature(Mips::FeatureDSP);
Jack Carterd76b2372013-03-21 21:44:16 +00002424 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00002425 // It is just an identifier, look for an assignment.
Jack Carterd76b2372013-03-21 21:44:16 +00002426 parseSetAssignment();
2427 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002428 }
Jack Carter07c818d2013-01-25 01:31:34 +00002429
Jack Carter0b744b32012-10-04 02:29:46 +00002430 return true;
2431}
2432
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002433/// parseDataDirective
Jack Carter07c818d2013-01-25 01:31:34 +00002434/// ::= .word [ expression (, expression)* ]
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002435bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
Jack Carter07c818d2013-01-25 01:31:34 +00002436 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2437 for (;;) {
2438 const MCExpr *Value;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002439 if (getParser().parseExpression(Value))
Jack Carter07c818d2013-01-25 01:31:34 +00002440 return true;
2441
2442 getParser().getStreamer().EmitValue(Value, Size);
2443
2444 if (getLexer().is(AsmToken::EndOfStatement))
2445 break;
2446
2447 // FIXME: Improve diagnostic.
2448 if (getLexer().isNot(AsmToken::Comma))
2449 return Error(L, "unexpected token in directive");
2450 Parser.Lex();
2451 }
2452 }
2453
2454 Parser.Lex();
2455 return false;
2456}
2457
Vladimir Medic4c299852013-11-06 11:27:05 +00002458/// parseDirectiveGpWord
2459/// ::= .gpword local_sym
2460bool MipsAsmParser::parseDirectiveGpWord() {
2461 const MCExpr *Value;
2462 // EmitGPRel32Value requires an expression, so we are using base class
2463 // method to evaluate the expression.
2464 if (getParser().parseExpression(Value))
2465 return true;
Vladimir Medic4c299852013-11-06 11:27:05 +00002466 getParser().getStreamer().EmitGPRel32Value(Value);
Vladimir Medic4c299852013-11-06 11:27:05 +00002467
Vladimir Medice10c1122013-11-13 13:18:04 +00002468 if (getLexer().isNot(AsmToken::EndOfStatement))
Vladimir Medic4c299852013-11-06 11:27:05 +00002469 return Error(getLexer().getLoc(), "unexpected token in directive");
Vladimir Medice10c1122013-11-13 13:18:04 +00002470 Parser.Lex(); // Eat EndOfStatement token.
Vladimir Medic4c299852013-11-06 11:27:05 +00002471 return false;
2472}
2473
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002474/// parseDirectiveGpDWord
Rafael Espindolab59fb732014-03-28 18:50:26 +00002475/// ::= .gpdword local_sym
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002476bool MipsAsmParser::parseDirectiveGpDWord() {
Rafael Espindolab59fb732014-03-28 18:50:26 +00002477 const MCExpr *Value;
2478 // EmitGPRel64Value requires an expression, so we are using base class
2479 // method to evaluate the expression.
2480 if (getParser().parseExpression(Value))
2481 return true;
2482 getParser().getStreamer().EmitGPRel64Value(Value);
2483
2484 if (getLexer().isNot(AsmToken::EndOfStatement))
2485 return Error(getLexer().getLoc(), "unexpected token in directive");
2486 Parser.Lex(); // Eat EndOfStatement token.
2487 return false;
2488}
2489
Jack Carter0cd3c192014-01-06 23:27:31 +00002490bool MipsAsmParser::parseDirectiveOption() {
2491 // Get the option token.
2492 AsmToken Tok = Parser.getTok();
2493 // At the moment only identifiers are supported.
2494 if (Tok.isNot(AsmToken::Identifier)) {
2495 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2496 Parser.eatToEndOfStatement();
2497 return false;
2498 }
2499
2500 StringRef Option = Tok.getIdentifier();
2501
2502 if (Option == "pic0") {
2503 getTargetStreamer().emitDirectiveOptionPic0();
2504 Parser.Lex();
2505 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2506 Error(Parser.getTok().getLoc(),
2507 "unexpected token in .option pic0 directive");
2508 Parser.eatToEndOfStatement();
2509 }
2510 return false;
2511 }
2512
Matheus Almeidaf79b2812014-03-26 13:40:29 +00002513 if (Option == "pic2") {
2514 getTargetStreamer().emitDirectiveOptionPic2();
2515 Parser.Lex();
2516 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2517 Error(Parser.getTok().getLoc(),
2518 "unexpected token in .option pic2 directive");
2519 Parser.eatToEndOfStatement();
2520 }
2521 return false;
2522 }
2523
Jack Carter0cd3c192014-01-06 23:27:31 +00002524 // Unknown option.
2525 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2526 Parser.eatToEndOfStatement();
2527 return false;
2528}
2529
Jack Carter0b744b32012-10-04 02:29:46 +00002530bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
Jack Carter07c818d2013-01-25 01:31:34 +00002531 StringRef IDVal = DirectiveID.getString();
2532
Matheus Almeida525bc4f2014-04-30 11:28:42 +00002533 if (IDVal == ".cpload")
2534 return parseDirectiveCPLoad(DirectiveID.getLoc());
Matheus Almeidaab5633b2014-03-26 15:44:18 +00002535 if (IDVal == ".dword") {
2536 parseDataDirective(8, DirectiveID.getLoc());
2537 return false;
2538 }
2539
Jack Carterd0bd6422013-04-18 00:41:53 +00002540 if (IDVal == ".ent") {
2541 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002542 Parser.Lex();
2543 return false;
2544 }
2545
Jack Carter07c818d2013-01-25 01:31:34 +00002546 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002547 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002548 Parser.Lex();
2549 return false;
2550 }
2551
Jack Carter07c818d2013-01-25 01:31:34 +00002552 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002553 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002554 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002555 return false;
2556 }
2557
Jack Carter07c818d2013-01-25 01:31:34 +00002558 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002559 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002560 }
2561
Jack Carter07c818d2013-01-25 01:31:34 +00002562 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002563 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002564 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002565 return false;
2566 }
2567
Jack Carter07c818d2013-01-25 01:31:34 +00002568 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002569 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002570 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002571 return false;
2572 }
2573
Matheus Almeida0051f2d2014-04-16 15:48:55 +00002574 if (IDVal == ".nan")
2575 return parseDirectiveNaN();
2576
Jack Carter07c818d2013-01-25 01:31:34 +00002577 if (IDVal == ".gpword") {
Vladimir Medic4c299852013-11-06 11:27:05 +00002578 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002579 return false;
2580 }
2581
Rafael Espindolab59fb732014-03-28 18:50:26 +00002582 if (IDVal == ".gpdword") {
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002583 parseDirectiveGpDWord();
Rafael Espindolab59fb732014-03-28 18:50:26 +00002584 return false;
2585 }
2586
Jack Carter07c818d2013-01-25 01:31:34 +00002587 if (IDVal == ".word") {
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002588 parseDataDirective(4, DirectiveID.getLoc());
Jack Carter07c818d2013-01-25 01:31:34 +00002589 return false;
2590 }
2591
Jack Carter0cd3c192014-01-06 23:27:31 +00002592 if (IDVal == ".option")
2593 return parseDirectiveOption();
2594
2595 if (IDVal == ".abicalls") {
2596 getTargetStreamer().emitDirectiveAbiCalls();
2597 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2598 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2599 // Clear line
2600 Parser.eatToEndOfStatement();
2601 }
2602 return false;
2603 }
2604
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002605 if (IDVal == ".cpsetup")
2606 return parseDirectiveCPSetup();
2607
Rafael Espindola870c4e92012-01-11 03:56:41 +00002608 return true;
2609}
2610
Rafael Espindola870c4e92012-01-11 03:56:41 +00002611extern "C" void LLVMInitializeMipsAsmParser() {
2612 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2613 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2614 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2615 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2616}
Jack Carterb4dbc172012-09-05 23:34:03 +00002617
2618#define GET_REGISTER_MATCHER
2619#define GET_MATCHER_IMPLEMENTATION
2620#include "MipsGenAsmMatcher.inc"