blob: 759a2db2839fd301ce2cd9908d7a2d4f886021ca [file] [log] [blame]
Jia Liu9f610112012-02-17 08:55:11 +00001//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
Rafael Espindola870c4e92012-01-11 03:56:41 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Petar Jovanovica5da5882014-02-04 18:41:57 +000010#include "MCTargetDesc/MipsMCExpr.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000011#include "MCTargetDesc/MipsMCTargetDesc.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000012#include "MipsRegisterInfo.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000013#include "MipsTargetStreamer.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000014#include "llvm/ADT/APInt.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000015#include "llvm/ADT/StringSwitch.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
Daniel Sandersa771fef2014-03-24 14:05:39 +000019#include "llvm/MC/MCInstBuilder.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/MC/MCParser/MCAsmLexer.h"
21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Jack Carterb4dbc172012-09-05 23:34:03 +000022#include "llvm/MC/MCStreamer.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/MC/MCSymbol.h"
Akira Hatanaka7605630c2012-08-17 20:16:42 +000025#include "llvm/MC/MCTargetAsmParser.h"
Daniel Sandersb50ccf82014-04-01 10:35:28 +000026#include "llvm/Support/Debug.h"
Matheus Almeidae0d75aa2013-12-13 11:11:02 +000027#include "llvm/Support/MathExtras.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000028#include "llvm/Support/TargetRegistry.h"
Rafael Espindola870c4e92012-01-11 03:56:41 +000029
30using namespace llvm;
31
Joey Gouly0e76fa72013-09-12 10:28:05 +000032namespace llvm {
33class MCInstrInfo;
34}
35
Rafael Espindola870c4e92012-01-11 03:56:41 +000036namespace {
Jack Carter0b744b32012-10-04 02:29:46 +000037class MipsAssemblerOptions {
38public:
Vladimir Medic4c299852013-11-06 11:27:05 +000039 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
Jack Carterb4dbc172012-09-05 23:34:03 +000040
Vladimir Medic4c299852013-11-06 11:27:05 +000041 unsigned getATRegNum() { return aTReg; }
Jack Carter0b744b32012-10-04 02:29:46 +000042 bool setATReg(unsigned Reg);
43
Vladimir Medic4c299852013-11-06 11:27:05 +000044 bool isReorder() { return reorder; }
45 void setReorder() { reorder = true; }
46 void setNoreorder() { reorder = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000047
Vladimir Medic4c299852013-11-06 11:27:05 +000048 bool isMacro() { return macro; }
49 void setMacro() { macro = true; }
50 void setNomacro() { macro = false; }
Jack Carter0b744b32012-10-04 02:29:46 +000051
52private:
53 unsigned aTReg;
54 bool reorder;
55 bool macro;
56};
57}
58
59namespace {
Rafael Espindola870c4e92012-01-11 03:56:41 +000060class MipsAsmParser : public MCTargetAsmParser {
Rafael Espindolaa17151a2013-10-08 13:08:17 +000061 MipsTargetStreamer &getTargetStreamer() {
Rafael Espindola4a1a3602014-01-14 01:21:46 +000062 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
Rafael Espindolaa17151a2013-10-08 13:08:17 +000063 return static_cast<MipsTargetStreamer &>(TS);
64 }
65
Jack Carterb4dbc172012-09-05 23:34:03 +000066 MCSubtargetInfo &STI;
67 MCAsmParser &Parser;
Jack Carter99d2afe2012-10-05 23:55:28 +000068 MipsAssemblerOptions Options;
Jack Carter0b744b32012-10-04 02:29:46 +000069
Akira Hatanaka7605630c2012-08-17 20:16:42 +000070#define GET_ASSEMBLER_HEADER
71#include "MipsGenAsmMatcher.inc"
72
Chad Rosier49963552012-10-13 00:26:04 +000073 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Vladimir Medic4c299852013-11-06 11:27:05 +000074 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
Chad Rosier49963552012-10-13 00:26:04 +000075 MCStreamer &Out, unsigned &ErrorInfo,
76 bool MatchingInlineAsm);
Rafael Espindola870c4e92012-01-11 03:56:41 +000077
Daniel Sandersb50ccf82014-04-01 10:35:28 +000078 /// Parse a register as used in CFI directives
Rafael Espindola870c4e92012-01-11 03:56:41 +000079 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
80
Daniel Sandersb50ccf82014-04-01 10:35:28 +000081 bool ParseParenSuffix(StringRef Name,
82 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
83
84 bool ParseBracketSuffix(StringRef Name,
85 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
86
Chad Rosierf0e87202012-10-25 20:41:34 +000087 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
88 SMLoc NameLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +000089 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Rafael Espindola870c4e92012-01-11 03:56:41 +000090
91 bool ParseDirective(AsmToken DirectiveID);
92
Jack Carterb4dbc172012-09-05 23:34:03 +000093 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +000094 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +000095
Daniel Sandersb50ccf82014-04-01 10:35:28 +000096 MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar(
97 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
98 SMLoc S);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +000099
100 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000101 ParseAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
102 SMLoc S);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000103
Jack Carter873c7242013-01-12 01:03:14 +0000104 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000105 ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000106
107 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000108 ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carter873c7242013-01-12 01:03:14 +0000109
110 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000111 ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000112
113 MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +0000114 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Vladimir Medic2b953d02013-10-01 09:48:56 +0000115
Matheus Almeida779c5932013-11-18 12:32:49 +0000116 MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000117 ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Matheus Almeida779c5932013-11-18 12:32:49 +0000118
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000119 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
Jack Carterd76b2372013-03-21 21:44:16 +0000120
Vladimir Medic4c299852013-11-06 11:27:05 +0000121 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
Jack Carterb4dbc172012-09-05 23:34:03 +0000122 StringRef Mnemonic);
123
Jack Carter30a59822012-10-04 04:03:53 +0000124 bool needsExpansion(MCInst &Inst);
125
126 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000127 SmallVectorImpl<MCInst> &Instructions);
Jack Carter30a59822012-10-04 04:03:53 +0000128 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carter92995f12012-10-06 00:53:28 +0000129 SmallVectorImpl<MCInst> &Instructions);
Jack Carter543fdf82012-10-09 23:29:45 +0000130 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
131 SmallVectorImpl<MCInst> &Instructions);
132 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
133 SmallVectorImpl<MCInst> &Instructions);
Jack Carter9e65aa32013-03-22 00:05:30 +0000134 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000135 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
136 bool isImmOpnd);
Jack Carter0b744b32012-10-04 02:29:46 +0000137 bool reportParseError(StringRef ErrorMsg);
138
Jack Carterb5cf5902013-04-17 00:18:04 +0000139 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
Jack Carter873c7242013-01-12 01:03:14 +0000140 bool parseRelocOperand(const MCExpr *&Res);
Jack Carter0b744b32012-10-04 02:29:46 +0000141
Vladimir Medic4c299852013-11-06 11:27:05 +0000142 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +0000143
144 bool isEvaluated(const MCExpr *Expr);
Matheus Almeidafe1e39d2014-03-26 14:26:27 +0000145 bool parseSetFeature(uint64_t Feature);
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000146 bool parseDirectiveCPSetup();
Jack Carter0b744b32012-10-04 02:29:46 +0000147 bool parseDirectiveSet();
Jack Carter0cd3c192014-01-06 23:27:31 +0000148 bool parseDirectiveOption();
Jack Carter0b744b32012-10-04 02:29:46 +0000149
150 bool parseSetAtDirective();
151 bool parseSetNoAtDirective();
152 bool parseSetMacroDirective();
153 bool parseSetNoMacroDirective();
154 bool parseSetReorderDirective();
155 bool parseSetNoReorderDirective();
Jack Carter39536722014-01-22 23:08:42 +0000156 bool parseSetNoMips16Directive();
Jack Carter0b744b32012-10-04 02:29:46 +0000157
Jack Carterd76b2372013-03-21 21:44:16 +0000158 bool parseSetAssignment();
159
Matheus Almeida3e2a7022014-03-26 15:24:36 +0000160 bool parseDataDirective(unsigned Size, SMLoc L);
Vladimir Medic4c299852013-11-06 11:27:05 +0000161 bool parseDirectiveGpWord();
Rafael Espindola2378d4c2014-03-31 14:15:07 +0000162 bool parseDirectiveGpDWord();
Jack Carter07c818d2013-01-25 01:31:34 +0000163
Jack Carterdc1e35d2012-09-06 20:00:02 +0000164 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
Jack Cartera63b16a2012-09-07 00:23:42 +0000165
Daniel Sanders5e94e682014-03-27 16:42:17 +0000166 bool isGP64() const {
167 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
Jack Carterb4dbc172012-09-05 23:34:03 +0000168 }
169
Jack Cartera63b16a2012-09-07 00:23:42 +0000170 bool isFP64() const {
171 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
172 }
173
Daniel Sandersa4b0c742014-03-26 11:39:07 +0000174 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
Vladimir Medic4c299852013-11-06 11:27:05 +0000175 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000176
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000177 bool isMicroMips() const {
178 return STI.getFeatureBits() & Mips::FeatureMicroMips;
179 }
180
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000181 bool parseRegister(unsigned &RegNum);
182
183 bool eatComma(StringRef ErrorStr);
184
Jack Carter1ac53222013-02-20 23:11:17 +0000185 int matchCPURegisterName(StringRef Symbol);
186
Jack Carter873c7242013-01-12 01:03:14 +0000187 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
Jack Carterb4dbc172012-09-05 23:34:03 +0000188
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000189 int matchFPURegisterName(StringRef Name);
Vladimir Medic8cd17102013-06-20 11:21:49 +0000190
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000191 int matchFCCRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000192
Vladimir Medic27c87ea2013-08-13 13:07:09 +0000193 int matchACRegisterName(StringRef Name);
Jack Cartera63b16a2012-09-07 00:23:42 +0000194
Jack Carter5dc8ac92013-09-25 23:50:44 +0000195 int matchMSA128RegisterName(StringRef Name);
196
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000197 int matchMSA128CtrlRegisterName(StringRef Name);
198
Jack Carterd0bd6422013-04-18 00:41:53 +0000199 unsigned getReg(int RC, int RegNo);
Chad Rosier391d29972012-09-03 18:47:45 +0000200
Daniel Sanders5bce5f62014-03-27 13:52:53 +0000201 unsigned getGPR(int RegNo);
202
Jack Carter1ac53222013-02-20 23:11:17 +0000203 int getATReg();
Jack Carter9e65aa32013-03-22 00:05:30 +0000204
205 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000206 SmallVectorImpl<MCInst> &Instructions);
Matheus Almeidab74293d2013-10-14 11:49:30 +0000207
208 // Helper function that checks if the value of a vector index is within the
209 // boundaries of accepted values for each RegisterKind
210 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
211 bool validateMSAIndex(int Val, int RegKind);
212
Vladimir Medic615b26e2014-03-04 09:54:09 +0000213 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
214 if (!(STI.getFeatureBits() & Feature)) {
215 setAvailableFeatures(ComputeAvailableFeatures(
216 STI.ToggleFeature(FeatureString)));
217 }
218 }
219
220 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
221 if (STI.getFeatureBits() & Feature) {
222 setAvailableFeatures(ComputeAvailableFeatures(
223 STI.ToggleFeature(FeatureString)));
224 }
225 }
226
Rafael Espindola870c4e92012-01-11 03:56:41 +0000227public:
Joey Gouly0e76fa72013-09-12 10:28:05 +0000228 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
229 const MCInstrInfo &MII)
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000230 : MCTargetAsmParser(), STI(sti), Parser(parser) {
Jack Carterb4dbc172012-09-05 23:34:03 +0000231 // Initialize the set of available features.
232 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
Daniel Sanders5a1449d2014-02-20 14:58:19 +0000233
234 // Assert exactly one ABI was chosen.
235 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
236 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
237 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
238 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000239 }
240
Jack Carterb4dbc172012-09-05 23:34:03 +0000241 MCAsmParser &getParser() const { return Parser; }
242 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000243
244 /// Warn if RegNo is the current assembler temporary.
245 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
Rafael Espindola870c4e92012-01-11 03:56:41 +0000246};
247}
248
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000249namespace {
250
251/// MipsOperand - Instances of this class represent a parsed Mips machine
252/// instruction.
253class MipsOperand : public MCParsedAsmOperand {
Daniel Sanderse34a1202014-03-31 18:51:43 +0000254public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000255 /// Broad categories of register classes
256 /// The exact class is finalized by the render method.
257 enum RegKind {
258 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64())
259 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
260 /// isFP64())
261 RegKind_FCC = 4, /// FCC
262 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
263 RegKind_MSACtrl = 16, /// MSA control registers
264 RegKind_COP2 = 32, /// COP2
265 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
266 /// context).
267 RegKind_CCR = 128, /// CCR
268 RegKind_HWRegs = 256, /// HWRegs
269
270 /// Potentially any (e.g. $1)
271 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
272 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
273 RegKind_CCR | RegKind_HWRegs
Jack Carter873c7242013-01-12 01:03:14 +0000274 };
275
276private:
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000277 enum KindTy {
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000278 k_Immediate,
279 k_Memory,
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000280 k_PhysRegister,
281 k_RegisterIndex,
282 k_Token
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000283 } Kind;
284
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000285 MipsOperand(KindTy K, MipsAsmParser &Parser)
286 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
287
288 /// For diagnostics, and checking the assembler temporary
289 MipsAsmParser &AsmParser;
Jack Carterb4dbc172012-09-05 23:34:03 +0000290
Eric Christopher8996c5d2013-03-15 00:42:55 +0000291 struct Token {
292 const char *Data;
293 unsigned Length;
294 };
295
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000296 struct PhysRegOp {
297 unsigned Num; /// Register Number
298 };
299
300 struct RegIdxOp {
301 unsigned Index; /// Index into the register class
302 RegKind Kind; /// Bitfield of the kinds it could possibly be
303 const MCRegisterInfo *RegInfo;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000304 };
305
306 struct ImmOp {
307 const MCExpr *Val;
308 };
309
310 struct MemOp {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000311 MipsOperand *Base;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000312 const MCExpr *Off;
313 };
314
Jack Carterb4dbc172012-09-05 23:34:03 +0000315 union {
Eric Christopher8996c5d2013-03-15 00:42:55 +0000316 struct Token Tok;
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000317 struct PhysRegOp PhysReg;
318 struct RegIdxOp RegIdx;
Eric Christopher8996c5d2013-03-15 00:42:55 +0000319 struct ImmOp Imm;
320 struct MemOp Mem;
Jack Carterb4dbc172012-09-05 23:34:03 +0000321 };
322
323 SMLoc StartLoc, EndLoc;
324
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000325 /// Internal constructor for register kinds
326 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
327 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
328 MipsAsmParser &Parser) {
329 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
330 Op->RegIdx.Index = Index;
331 Op->RegIdx.RegInfo = RegInfo;
332 Op->RegIdx.Kind = RegKind;
333 Op->StartLoc = S;
334 Op->EndLoc = E;
335 return Op;
336 }
337
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000338public:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000339 /// Coerce the register to GPR32 and return the real register for the current
340 /// target.
341 unsigned getGPR32Reg() const {
342 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
343 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
344 unsigned ClassID = Mips::GPR32RegClassID;
345 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000346 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000347
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000348 /// Coerce the register to GPR64 and return the real register for the current
349 /// target.
350 unsigned getGPR64Reg() const {
351 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
352 unsigned ClassID = Mips::GPR64RegClassID;
353 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000354 }
355
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000356private:
357 /// Coerce the register to AFGR64 and return the real register for the current
358 /// target.
359 unsigned getAFGR64Reg() const {
360 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
361 if (RegIdx.Index % 2 != 0)
362 AsmParser.Warning(StartLoc, "Float register should be even.");
363 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
364 .getRegister(RegIdx.Index / 2);
365 }
366
367 /// Coerce the register to FGR64 and return the real register for the current
368 /// target.
369 unsigned getFGR64Reg() const {
370 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
371 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
372 .getRegister(RegIdx.Index);
373 }
374
375 /// Coerce the register to FGR32 and return the real register for the current
376 /// target.
377 unsigned getFGR32Reg() const {
378 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
379 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
380 .getRegister(RegIdx.Index);
381 }
382
383 /// Coerce the register to FGRH32 and return the real register for the current
384 /// target.
385 unsigned getFGRH32Reg() const {
386 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
387 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
388 .getRegister(RegIdx.Index);
389 }
390
391 /// Coerce the register to FCC and return the real register for the current
392 /// target.
393 unsigned getFCCReg() const {
394 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
395 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
396 .getRegister(RegIdx.Index);
397 }
398
399 /// Coerce the register to MSA128 and return the real register for the current
400 /// target.
401 unsigned getMSA128Reg() const {
402 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
403 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
404 // identical
405 unsigned ClassID = Mips::MSA128BRegClassID;
406 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
407 }
408
409 /// Coerce the register to MSACtrl and return the real register for the
410 /// current target.
411 unsigned getMSACtrlReg() const {
412 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
413 unsigned ClassID = Mips::MSACtrlRegClassID;
414 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
415 }
416
417 /// Coerce the register to COP2 and return the real register for the
418 /// current target.
419 unsigned getCOP2Reg() const {
420 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
421 unsigned ClassID = Mips::COP2RegClassID;
422 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
423 }
424
425 /// Coerce the register to ACC64DSP and return the real register for the
426 /// current target.
427 unsigned getACC64DSPReg() const {
428 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
429 unsigned ClassID = Mips::ACC64DSPRegClassID;
430 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
431 }
432
433 /// Coerce the register to HI32DSP and return the real register for the
434 /// current target.
435 unsigned getHI32DSPReg() const {
436 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
437 unsigned ClassID = Mips::HI32DSPRegClassID;
438 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
439 }
440
441 /// Coerce the register to LO32DSP and return the real register for the
442 /// current target.
443 unsigned getLO32DSPReg() const {
444 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
445 unsigned ClassID = Mips::LO32DSPRegClassID;
446 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
447 }
448
449 /// Coerce the register to CCR and return the real register for the
450 /// current target.
451 unsigned getCCRReg() const {
452 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
453 unsigned ClassID = Mips::CCRRegClassID;
454 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
455 }
456
457 /// Coerce the register to HWRegs and return the real register for the
458 /// current target.
459 unsigned getHWRegsReg() const {
460 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
461 unsigned ClassID = Mips::HWRegsRegClassID;
462 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
463 }
464
465public:
Vladimir Medic4c299852013-11-06 11:27:05 +0000466 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000467 // Add as immediate when possible. Null MCExpr = 0.
468 if (Expr == 0)
469 Inst.addOperand(MCOperand::CreateImm(0));
470 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
471 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
472 else
473 Inst.addOperand(MCOperand::CreateExpr(Expr));
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000474 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000475
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000476 void addRegOperands(MCInst &Inst, unsigned N) const {
477 llvm_unreachable("Use a custom parser instead");
478 }
479
480 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
481 assert(N == 1 && "Invalid number of operands!");
482 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
483 }
484
485 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
486 assert(N == 1 && "Invalid number of operands!");
487 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
488 }
489
490 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
491 assert(N == 1 && "Invalid number of operands!");
492 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
493 }
494
495 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
496 assert(N == 1 && "Invalid number of operands!");
497 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
498 }
499
500 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
501 assert(N == 1 && "Invalid number of operands!");
502 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
503 }
504
505 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
506 assert(N == 1 && "Invalid number of operands!");
507 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
508 }
509
510 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
511 assert(N == 1 && "Invalid number of operands!");
512 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
513 }
514
515 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
516 assert(N == 1 && "Invalid number of operands!");
517 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
518 }
519
520 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
521 assert(N == 1 && "Invalid number of operands!");
522 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
523 }
524
525 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
526 assert(N == 1 && "Invalid number of operands!");
527 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
528 }
529
530 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
531 assert(N == 1 && "Invalid number of operands!");
532 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
533 }
534
535 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
536 assert(N == 1 && "Invalid number of operands!");
537 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
538 }
539
540 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
541 assert(N == 1 && "Invalid number of operands!");
542 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
543 }
544
545 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
546 assert(N == 1 && "Invalid number of operands!");
547 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
548 }
549
550 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
551 assert(N == 1 && "Invalid number of operands!");
552 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
553 }
554
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000555 void addImmOperands(MCInst &Inst, unsigned N) const {
Jack Carterb4dbc172012-09-05 23:34:03 +0000556 assert(N == 1 && "Invalid number of operands!");
557 const MCExpr *Expr = getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +0000558 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000559 }
Jack Carterb4dbc172012-09-05 23:34:03 +0000560
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000561 void addMemOperands(MCInst &Inst, unsigned N) const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000562 assert(N == 2 && "Invalid number of operands!");
563
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000564 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
Jack Carterdc1e35d2012-09-06 20:00:02 +0000565
566 const MCExpr *Expr = getMemOff();
Jack Carterd0bd6422013-04-18 00:41:53 +0000567 addExpr(Inst, Expr);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000568 }
569
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000570 bool isReg() const {
571 // As a special case until we sort out the definition of div/divu, pretend
572 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
573 if (isGPRAsmReg() && RegIdx.Index == 0)
574 return true;
575
576 return Kind == k_PhysRegister;
577 }
578 bool isRegIdx() const { return Kind == k_RegisterIndex; }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000579 bool isImm() const { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000580 bool isConstantImm() const {
581 return isImm() && dyn_cast<MCConstantExpr>(getImm());
582 }
583 bool isToken() const {
584 // Note: It's not possible to pretend that other operand kinds are tokens.
585 // The matcher emitter checks tokens first.
586 return Kind == k_Token;
587 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000588 bool isMem() const { return Kind == k_Memory; }
Vladimir Medic2b953d02013-10-01 09:48:56 +0000589 bool isInvNum() const { return Kind == k_Immediate; }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000590 bool isLSAImm() const {
591 if (!isConstantImm())
592 return false;
593 int64_t Val = getConstantImm();
594 return 1 <= Val && Val <= 4;
595 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000596
597 StringRef getToken() const {
598 assert(Kind == k_Token && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000599 return StringRef(Tok.Data, Tok.Length);
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000600 }
601
602 unsigned getReg() const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000603 // As a special case until we sort out the definition of div/divu, pretend
604 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
605 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
606 RegIdx.Kind & RegKind_GPR)
607 return getGPR32Reg(); // FIXME: GPR64 too
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000608
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000609 assert(Kind == k_PhysRegister && "Invalid access!");
610 return PhysReg.Num;
Jack Carter873c7242013-01-12 01:03:14 +0000611 }
612
Jack Carterb4dbc172012-09-05 23:34:03 +0000613 const MCExpr *getImm() const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000614 assert((Kind == k_Immediate) && "Invalid access!");
Jack Carterb4dbc172012-09-05 23:34:03 +0000615 return Imm.Val;
616 }
617
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000618 int64_t getConstantImm() const {
619 const MCExpr *Val = getImm();
620 return static_cast<const MCConstantExpr *>(Val)->getValue();
621 }
622
623 MipsOperand *getMemBase() const {
Jack Carterdc1e35d2012-09-06 20:00:02 +0000624 assert((Kind == k_Memory) && "Invalid access!");
625 return Mem.Base;
626 }
627
628 const MCExpr *getMemOff() const {
629 assert((Kind == k_Memory) && "Invalid access!");
630 return Mem.Off;
631 }
632
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000633 static MipsOperand *CreateToken(StringRef Str, SMLoc S,
634 MipsAsmParser &Parser) {
635 MipsOperand *Op = new MipsOperand(k_Token, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000636 Op->Tok.Data = Str.data();
637 Op->Tok.Length = Str.size();
638 Op->StartLoc = S;
639 Op->EndLoc = S;
640 return Op;
641 }
642
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000643 /// Create a numeric register (e.g. $1). The exact register remains
644 /// unresolved until an instruction successfully matches
645 static MipsOperand *CreateNumericReg(unsigned Index,
646 const MCRegisterInfo *RegInfo, SMLoc S,
647 SMLoc E, MipsAsmParser &Parser) {
648 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
649 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000650 }
651
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000652 /// Create a register that is definitely a GPR.
653 /// This is typically only used for named registers such as $gp.
654 static MipsOperand *CreateGPRReg(unsigned Index,
655 const MCRegisterInfo *RegInfo, SMLoc S,
656 SMLoc E, MipsAsmParser &Parser) {
657 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
Akira Hatanaka9bfa2e22013-08-28 00:55:15 +0000658 }
659
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000660 /// Create a register that is definitely a FGR.
661 /// This is typically only used for named registers such as $f0.
662 static MipsOperand *CreateFGRReg(unsigned Index,
663 const MCRegisterInfo *RegInfo, SMLoc S,
664 SMLoc E, MipsAsmParser &Parser) {
665 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
666 }
667
668 /// Create a register that is definitely an FCC.
669 /// This is typically only used for named registers such as $fcc0.
670 static MipsOperand *CreateFCCReg(unsigned Index,
671 const MCRegisterInfo *RegInfo, SMLoc S,
672 SMLoc E, MipsAsmParser &Parser) {
673 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
674 }
675
676 /// Create a register that is definitely an ACC.
677 /// This is typically only used for named registers such as $ac0.
678 static MipsOperand *CreateACCReg(unsigned Index,
679 const MCRegisterInfo *RegInfo, SMLoc S,
680 SMLoc E, MipsAsmParser &Parser) {
681 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
682 }
683
684 /// Create a register that is definitely an MSA128.
685 /// This is typically only used for named registers such as $w0.
686 static MipsOperand *CreateMSA128Reg(unsigned Index,
687 const MCRegisterInfo *RegInfo, SMLoc S,
688 SMLoc E, MipsAsmParser &Parser) {
689 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
690 }
691
692 /// Create a register that is definitely an MSACtrl.
693 /// This is typically only used for named registers such as $msaaccess.
694 static MipsOperand *CreateMSACtrlReg(unsigned Index,
695 const MCRegisterInfo *RegInfo, SMLoc S,
696 SMLoc E, MipsAsmParser &Parser) {
697 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
698 }
699
700 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
701 MipsAsmParser &Parser) {
702 MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
Jack Carterb4dbc172012-09-05 23:34:03 +0000703 Op->Imm.Val = Val;
704 Op->StartLoc = S;
705 Op->EndLoc = E;
706 return Op;
707 }
708
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000709 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
710 SMLoc E, MipsAsmParser &Parser) {
711 MipsOperand *Op = new MipsOperand(k_Memory, Parser);
Jack Carterdc1e35d2012-09-06 20:00:02 +0000712 Op->Mem.Base = Base;
713 Op->Mem.Off = Off;
714 Op->StartLoc = S;
715 Op->EndLoc = E;
716 return Op;
717 }
718
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000719 bool isGPRAsmReg() const {
720 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000721 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000722 bool isFGRAsmReg() const {
723 // AFGR64 is $0-$15 but we handle this in getAFGR64()
724 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000725 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000726 bool isHWRegsAsmReg() const {
727 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000728 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000729 bool isCCRAsmReg() const {
730 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
Jack Carter873c7242013-01-12 01:03:14 +0000731 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000732 bool isFCCAsmReg() const {
733 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
Jack Carter873c7242013-01-12 01:03:14 +0000734 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000735 bool isACCAsmReg() const {
736 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
Vladimir Medic233dd512013-06-24 10:05:34 +0000737 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000738 bool isCOP2AsmReg() const {
739 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000740 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000741 bool isMSA128AsmReg() const {
742 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
Vladimir Medic233dd512013-06-24 10:05:34 +0000743 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000744 bool isMSACtrlAsmReg() const {
745 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
Matheus Almeidaa591fdc2013-10-21 12:26:50 +0000746 }
747
Jack Carterb4dbc172012-09-05 23:34:03 +0000748 /// getStartLoc - Get the location of the first token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000749 SMLoc getStartLoc() const { return StartLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000750 /// getEndLoc - Get the location of the last token of this operand.
Vladimir Medic4c299852013-11-06 11:27:05 +0000751 SMLoc getEndLoc() const { return EndLoc; }
Jack Carterb4dbc172012-09-05 23:34:03 +0000752
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000753 virtual void print(raw_ostream &OS) const {
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000754 switch (Kind) {
755 case k_Immediate:
756 OS << "Imm<";
757 Imm.Val->print(OS);
758 OS << ">";
759 break;
760 case k_Memory:
761 OS << "Mem<";
762 Mem.Base->print(OS);
763 OS << ", ";
764 Mem.Off->print(OS);
765 OS << ">";
766 break;
767 case k_PhysRegister:
768 OS << "PhysReg<" << PhysReg.Num << ">";
769 break;
770 case k_RegisterIndex:
771 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
772 break;
773 case k_Token:
774 OS << Tok.Data;
775 break;
776 }
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000777 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000778}; // class MipsOperand
Vladimir Medic4c299852013-11-06 11:27:05 +0000779} // namespace
Akira Hatanaka7605630c2012-08-17 20:16:42 +0000780
Jack Carter9e65aa32013-03-22 00:05:30 +0000781namespace llvm {
782extern const MCInstrDesc MipsInsts[];
783}
784static const MCInstrDesc &getInstDesc(unsigned Opcode) {
785 return MipsInsts[Opcode];
786}
787
788bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
Jack Carterb5cf5902013-04-17 00:18:04 +0000789 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000790 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
Daniel Sandersa771fef2014-03-24 14:05:39 +0000791
Jack Carter9e65aa32013-03-22 00:05:30 +0000792 Inst.setLoc(IDLoc);
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000793
794 if (MCID.isBranch() || MCID.isCall()) {
795 const unsigned Opcode = Inst.getOpcode();
796 MCOperand Offset;
797
798 switch (Opcode) {
799 default:
800 break;
801 case Mips::BEQ:
802 case Mips::BNE:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000803 case Mips::BEQ_MM:
804 case Mips::BNE_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000805 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000806 Offset = Inst.getOperand(2);
807 if (!Offset.isImm())
808 break; // We'll deal with this situation later on when applying fixups.
809 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
810 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000811 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000812 return Error(IDLoc, "branch to misaligned address");
813 break;
814 case Mips::BGEZ:
815 case Mips::BGTZ:
816 case Mips::BLEZ:
817 case Mips::BLTZ:
818 case Mips::BGEZAL:
819 case Mips::BLTZAL:
820 case Mips::BC1F:
821 case Mips::BC1T:
Daniel Sandersb50ccf82014-04-01 10:35:28 +0000822 case Mips::BGEZ_MM:
823 case Mips::BGTZ_MM:
824 case Mips::BLEZ_MM:
825 case Mips::BLTZ_MM:
826 case Mips::BGEZAL_MM:
827 case Mips::BLTZAL_MM:
828 case Mips::BC1F_MM:
829 case Mips::BC1T_MM:
Jack Carter3b2c96e2014-01-22 23:31:38 +0000830 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000831 Offset = Inst.getOperand(1);
832 if (!Offset.isImm())
833 break; // We'll deal with this situation later on when applying fixups.
834 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
835 return Error(IDLoc, "branch target out of range");
Jack Carter3b2c96e2014-01-22 23:31:38 +0000836 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
Matheus Almeidae0d75aa2013-12-13 11:11:02 +0000837 return Error(IDLoc, "branch to misaligned address");
838 break;
839 }
840 }
841
Jack Carterc15c1d22013-04-25 23:31:35 +0000842 if (MCID.hasDelaySlot() && Options.isReorder()) {
843 // If this instruction has a delay slot and .set reorder is active,
844 // emit a NOP after it.
845 Instructions.push_back(Inst);
846 MCInst NopInst;
847 NopInst.setOpcode(Mips::SLL);
848 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
849 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
850 NopInst.addOperand(MCOperand::CreateImm(0));
851 Instructions.push_back(NopInst);
852 return false;
853 }
854
Jack Carter9e65aa32013-03-22 00:05:30 +0000855 if (MCID.mayLoad() || MCID.mayStore()) {
856 // Check the offset of memory operand, if it is a symbol
Jack Carterd0bd6422013-04-18 00:41:53 +0000857 // reference or immediate we may have to expand instructions.
858 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000859 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
Vladimir Medic4c299852013-11-06 11:27:05 +0000860 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
861 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000862 MCOperand &Op = Inst.getOperand(i);
863 if (Op.isImm()) {
864 int MemOffset = Op.getImm();
865 if (MemOffset < -32768 || MemOffset > 32767) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000866 // Offset can't exceed 16bit value.
867 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
Jack Carter9e65aa32013-03-22 00:05:30 +0000868 return false;
869 }
870 } else if (Op.isExpr()) {
871 const MCExpr *Expr = Op.getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +0000872 if (Expr->getKind() == MCExpr::SymbolRef) {
Jack Carter9e65aa32013-03-22 00:05:30 +0000873 const MCSymbolRefExpr *SR =
Vladimir Medic4c299852013-11-06 11:27:05 +0000874 static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carter9e65aa32013-03-22 00:05:30 +0000875 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000876 // Expand symbol.
877 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carter9e65aa32013-03-22 00:05:30 +0000878 return false;
879 }
Jack Carterb5cf5902013-04-17 00:18:04 +0000880 } else if (!isEvaluated(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000881 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
Jack Carterb5cf5902013-04-17 00:18:04 +0000882 return false;
Jack Carter9e65aa32013-03-22 00:05:30 +0000883 }
884 }
885 }
Jack Carterd0bd6422013-04-18 00:41:53 +0000886 } // for
Vladimir Medic4c299852013-11-06 11:27:05 +0000887 } // if load/store
Jack Carter9e65aa32013-03-22 00:05:30 +0000888
889 if (needsExpansion(Inst))
890 expandInstruction(Inst, IDLoc, Instructions);
891 else
892 Instructions.push_back(Inst);
893
894 return false;
895}
896
Jack Carter30a59822012-10-04 04:03:53 +0000897bool MipsAsmParser::needsExpansion(MCInst &Inst) {
898
Jack Carterd0bd6422013-04-18 00:41:53 +0000899 switch (Inst.getOpcode()) {
900 case Mips::LoadImm32Reg:
901 case Mips::LoadAddr32Imm:
902 case Mips::LoadAddr32Reg:
Daniel Sandersa771fef2014-03-24 14:05:39 +0000903 case Mips::SUBi:
904 case Mips::SUBiu:
905 case Mips::DSUBi:
906 case Mips::DSUBiu:
Jack Carterd0bd6422013-04-18 00:41:53 +0000907 return true;
908 default:
909 return false;
Jack Carter30a59822012-10-04 04:03:53 +0000910 }
911}
Jack Carter92995f12012-10-06 00:53:28 +0000912
Jack Carter30a59822012-10-04 04:03:53 +0000913void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +0000914 SmallVectorImpl<MCInst> &Instructions) {
Jack Carterd0bd6422013-04-18 00:41:53 +0000915 switch (Inst.getOpcode()) {
916 case Mips::LoadImm32Reg:
917 return expandLoadImm(Inst, IDLoc, Instructions);
918 case Mips::LoadAddr32Imm:
919 return expandLoadAddressImm(Inst, IDLoc, Instructions);
920 case Mips::LoadAddr32Reg:
921 return expandLoadAddressReg(Inst, IDLoc, Instructions);
Daniel Sandersa771fef2014-03-24 14:05:39 +0000922 case Mips::SUBi:
923 Instructions.push_back(MCInstBuilder(Mips::ADDi)
924 .addReg(Inst.getOperand(0).getReg())
925 .addReg(Inst.getOperand(1).getReg())
926 .addImm(-Inst.getOperand(2).getImm()));
927 return;
928 case Mips::SUBiu:
929 Instructions.push_back(MCInstBuilder(Mips::ADDiu)
930 .addReg(Inst.getOperand(0).getReg())
931 .addReg(Inst.getOperand(1).getReg())
932 .addImm(-Inst.getOperand(2).getImm()));
933 return;
934 case Mips::DSUBi:
935 Instructions.push_back(MCInstBuilder(Mips::DADDi)
936 .addReg(Inst.getOperand(0).getReg())
937 .addReg(Inst.getOperand(1).getReg())
938 .addImm(-Inst.getOperand(2).getImm()));
939 return;
940 case Mips::DSUBiu:
941 Instructions.push_back(MCInstBuilder(Mips::DADDiu)
942 .addReg(Inst.getOperand(0).getReg())
943 .addReg(Inst.getOperand(1).getReg())
944 .addImm(-Inst.getOperand(2).getImm()));
945 return;
Jack Carterd0bd6422013-04-18 00:41:53 +0000946 }
Jack Carter30a59822012-10-04 04:03:53 +0000947}
Jack Carter92995f12012-10-06 00:53:28 +0000948
Jack Carter30a59822012-10-04 04:03:53 +0000949void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
Jack Carterd0bd6422013-04-18 00:41:53 +0000950 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter92995f12012-10-06 00:53:28 +0000951 MCInst tmpInst;
Jack Carter30a59822012-10-04 04:03:53 +0000952 const MCOperand &ImmOp = Inst.getOperand(1);
Jack Carter543fdf82012-10-09 23:29:45 +0000953 assert(ImmOp.isImm() && "expected immediate operand kind");
Jack Carter30a59822012-10-04 04:03:53 +0000954 const MCOperand &RegOp = Inst.getOperand(0);
955 assert(RegOp.isReg() && "expected register operand kind");
956
957 int ImmValue = ImmOp.getImm();
Jack Carter92995f12012-10-06 00:53:28 +0000958 tmpInst.setLoc(IDLoc);
Jack Carterd0bd6422013-04-18 00:41:53 +0000959 if (0 <= ImmValue && ImmValue <= 65535) {
960 // For 0 <= j <= 65535.
Jack Carter30a59822012-10-04 04:03:53 +0000961 // li d,j => ori d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000962 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000963 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000964 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000965 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000966 Instructions.push_back(tmpInst);
Jack Carterd0bd6422013-04-18 00:41:53 +0000967 } else if (ImmValue < 0 && ImmValue >= -32768) {
968 // For -32768 <= j < 0.
Jack Carter30a59822012-10-04 04:03:53 +0000969 // li d,j => addiu d,$zero,j
Jack Carter873c7242013-01-12 01:03:14 +0000970 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter92995f12012-10-06 00:53:28 +0000971 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +0000972 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter92995f12012-10-06 00:53:28 +0000973 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Jack Carter30a59822012-10-04 04:03:53 +0000974 Instructions.push_back(tmpInst);
975 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +0000976 // For any other value of j that is representable as a 32-bit integer.
Jack Carter30a59822012-10-04 04:03:53 +0000977 // li d,j => lui d,hi16(j)
Jack Carter543fdf82012-10-09 23:29:45 +0000978 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +0000979 tmpInst.setOpcode(Mips::LUi);
Jack Carter92995f12012-10-06 00:53:28 +0000980 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
981 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
Jack Carter30a59822012-10-04 04:03:53 +0000982 Instructions.push_back(tmpInst);
Jack Carter92995f12012-10-06 00:53:28 +0000983 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +0000984 tmpInst.setOpcode(Mips::ORi);
Jack Carter92995f12012-10-06 00:53:28 +0000985 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
986 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
987 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
988 tmpInst.setLoc(IDLoc);
Jack Carter30a59822012-10-04 04:03:53 +0000989 Instructions.push_back(tmpInst);
990 }
991}
Jack Carter92995f12012-10-06 00:53:28 +0000992
Vladimir Medic4c299852013-11-06 11:27:05 +0000993void
994MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
995 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +0000996 MCInst tmpInst;
997 const MCOperand &ImmOp = Inst.getOperand(2);
998 assert(ImmOp.isImm() && "expected immediate operand kind");
999 const MCOperand &SrcRegOp = Inst.getOperand(1);
1000 assert(SrcRegOp.isReg() && "expected register operand kind");
1001 const MCOperand &DstRegOp = Inst.getOperand(0);
1002 assert(DstRegOp.isReg() && "expected register operand kind");
1003 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001004 if (-32768 <= ImmValue && ImmValue <= 65535) {
1005 // For -32768 <= j <= 65535.
1006 // la d,j(s) => addiu d,s,j
Jack Carter873c7242013-01-12 01:03:14 +00001007 tmpInst.setOpcode(Mips::ADDiu);
Jack Carter543fdf82012-10-09 23:29:45 +00001008 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1009 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1010 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1011 Instructions.push_back(tmpInst);
1012 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001013 // For any other value of j that is representable as a 32-bit integer.
1014 // la d,j(s) => lui d,hi16(j)
1015 // ori d,d,lo16(j)
1016 // addu d,d,s
Jack Carter873c7242013-01-12 01:03:14 +00001017 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001018 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1019 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1020 Instructions.push_back(tmpInst);
1021 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001022 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001023 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1024 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1025 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1026 Instructions.push_back(tmpInst);
1027 tmpInst.clear();
1028 tmpInst.setOpcode(Mips::ADDu);
1029 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1030 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1031 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1032 Instructions.push_back(tmpInst);
1033 }
1034}
1035
Vladimir Medic4c299852013-11-06 11:27:05 +00001036void
1037MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1038 SmallVectorImpl<MCInst> &Instructions) {
Jack Carter543fdf82012-10-09 23:29:45 +00001039 MCInst tmpInst;
1040 const MCOperand &ImmOp = Inst.getOperand(1);
1041 assert(ImmOp.isImm() && "expected immediate operand kind");
1042 const MCOperand &RegOp = Inst.getOperand(0);
1043 assert(RegOp.isReg() && "expected register operand kind");
1044 int ImmValue = ImmOp.getImm();
Jack Carterd0bd6422013-04-18 00:41:53 +00001045 if (-32768 <= ImmValue && ImmValue <= 65535) {
1046 // For -32768 <= j <= 65535.
1047 // la d,j => addiu d,$zero,j
Jack Carter543fdf82012-10-09 23:29:45 +00001048 tmpInst.setOpcode(Mips::ADDiu);
1049 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
Jack Carterd0bd6422013-04-18 00:41:53 +00001050 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
Jack Carter543fdf82012-10-09 23:29:45 +00001051 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1052 Instructions.push_back(tmpInst);
1053 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001054 // For any other value of j that is representable as a 32-bit integer.
1055 // la d,j => lui d,hi16(j)
1056 // ori d,d,lo16(j)
Jack Carter873c7242013-01-12 01:03:14 +00001057 tmpInst.setOpcode(Mips::LUi);
Jack Carter543fdf82012-10-09 23:29:45 +00001058 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1059 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1060 Instructions.push_back(tmpInst);
1061 tmpInst.clear();
Jack Carter873c7242013-01-12 01:03:14 +00001062 tmpInst.setOpcode(Mips::ORi);
Jack Carter543fdf82012-10-09 23:29:45 +00001063 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1064 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1065 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1066 Instructions.push_back(tmpInst);
1067 }
1068}
1069
Jack Carter9e65aa32013-03-22 00:05:30 +00001070void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
Vladimir Medic4c299852013-11-06 11:27:05 +00001071 SmallVectorImpl<MCInst> &Instructions,
1072 bool isLoad, bool isImmOpnd) {
Jack Carter9e65aa32013-03-22 00:05:30 +00001073 const MCSymbolRefExpr *SR;
1074 MCInst TempInst;
Jack Carterd0bd6422013-04-18 00:41:53 +00001075 unsigned ImmOffset, HiOffset, LoOffset;
Jack Carter9e65aa32013-03-22 00:05:30 +00001076 const MCExpr *ExprOffset;
1077 unsigned TmpRegNum;
Vladimir Medic4c299852013-11-06 11:27:05 +00001078 unsigned AtRegNum = getReg(
Daniel Sanders5e94e682014-03-27 16:42:17 +00001079 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
Jack Carterd0bd6422013-04-18 00:41:53 +00001080 // 1st operand is either the source or destination register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001081 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1082 unsigned RegOpNum = Inst.getOperand(0).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001083 // 2nd operand is the base register.
Jack Carter9e65aa32013-03-22 00:05:30 +00001084 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1085 unsigned BaseRegNum = Inst.getOperand(1).getReg();
Jack Carterd0bd6422013-04-18 00:41:53 +00001086 // 3rd operand is either an immediate or expression.
Jack Carter9e65aa32013-03-22 00:05:30 +00001087 if (isImmOpnd) {
1088 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1089 ImmOffset = Inst.getOperand(2).getImm();
1090 LoOffset = ImmOffset & 0x0000ffff;
1091 HiOffset = (ImmOffset & 0xffff0000) >> 16;
Jack Carterd0bd6422013-04-18 00:41:53 +00001092 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
Jack Carter9e65aa32013-03-22 00:05:30 +00001093 if (LoOffset & 0x8000)
1094 HiOffset++;
Jack Carterd0bd6422013-04-18 00:41:53 +00001095 } else
Jack Carter9e65aa32013-03-22 00:05:30 +00001096 ExprOffset = Inst.getOperand(2).getExpr();
Jack Carterd0bd6422013-04-18 00:41:53 +00001097 // All instructions will have the same location.
Jack Carter9e65aa32013-03-22 00:05:30 +00001098 TempInst.setLoc(IDLoc);
1099 // 1st instruction in expansion is LUi. For load instruction we can use
1100 // the dst register as a temporary if base and dst are different,
Jack Carterd0bd6422013-04-18 00:41:53 +00001101 // but for stores we must use $at.
1102 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
Jack Carter9e65aa32013-03-22 00:05:30 +00001103 TempInst.setOpcode(Mips::LUi);
1104 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1105 if (isImmOpnd)
1106 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1107 else {
1108 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001109 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
Jack Carterd0bd6422013-04-18 00:41:53 +00001110 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1111 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1112 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001113 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001114 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001115 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
Jack Carterb5cf5902013-04-17 00:18:04 +00001116 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001117 }
1118 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001119 // Add the instruction to the list.
Jack Carter9e65aa32013-03-22 00:05:30 +00001120 Instructions.push_back(TempInst);
Jack Carterd0bd6422013-04-18 00:41:53 +00001121 // Prepare TempInst for next instruction.
Jack Carter9e65aa32013-03-22 00:05:30 +00001122 TempInst.clear();
Jack Carterd0bd6422013-04-18 00:41:53 +00001123 // Add temp register to base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001124 TempInst.setOpcode(Mips::ADDu);
1125 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1126 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1127 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1128 Instructions.push_back(TempInst);
1129 TempInst.clear();
Alp Tokercb402912014-01-24 17:20:08 +00001130 // And finally, create original instruction with low part
Jack Carterd0bd6422013-04-18 00:41:53 +00001131 // of offset and new base.
Jack Carter9e65aa32013-03-22 00:05:30 +00001132 TempInst.setOpcode(Inst.getOpcode());
1133 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1134 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1135 if (isImmOpnd)
1136 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1137 else {
1138 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001139 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1140 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1141 getContext());
Jack Carter9e65aa32013-03-22 00:05:30 +00001142 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carterb5cf5902013-04-17 00:18:04 +00001143 } else {
Jack Carterd0bd6422013-04-18 00:41:53 +00001144 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
Jack Carterb5cf5902013-04-17 00:18:04 +00001145 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
Jack Carter9e65aa32013-03-22 00:05:30 +00001146 }
1147 }
1148 Instructions.push_back(TempInst);
1149 TempInst.clear();
1150}
1151
Vladimir Medic4c299852013-11-06 11:27:05 +00001152bool MipsAsmParser::MatchAndEmitInstruction(
1153 SMLoc IDLoc, unsigned &Opcode,
1154 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
1155 unsigned &ErrorInfo, bool MatchingInlineAsm) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001156 MCInst Inst;
Jack Carter9e65aa32013-03-22 00:05:30 +00001157 SmallVector<MCInst, 8> Instructions;
Vladimir Medic4c299852013-11-06 11:27:05 +00001158 unsigned MatchResult =
1159 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
Jack Carterb4dbc172012-09-05 23:34:03 +00001160
1161 switch (MatchResult) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001162 default:
1163 break;
Jack Carterb4dbc172012-09-05 23:34:03 +00001164 case Match_Success: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001165 if (processInstruction(Inst, IDLoc, Instructions))
Jack Carter9e65aa32013-03-22 00:05:30 +00001166 return true;
Jack Carterd0bd6422013-04-18 00:41:53 +00001167 for (unsigned i = 0; i < Instructions.size(); i++)
David Woodhousee6c13e42014-01-28 23:12:42 +00001168 Out.EmitInstruction(Instructions[i], STI);
Jack Carterb4dbc172012-09-05 23:34:03 +00001169 return false;
1170 }
1171 case Match_MissingFeature:
1172 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1173 return true;
1174 case Match_InvalidOperand: {
1175 SMLoc ErrorLoc = IDLoc;
1176 if (ErrorInfo != ~0U) {
1177 if (ErrorInfo >= Operands.size())
1178 return Error(IDLoc, "too few operands for instruction");
1179
Vladimir Medic4c299852013-11-06 11:27:05 +00001180 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
Jack Carterd0bd6422013-04-18 00:41:53 +00001181 if (ErrorLoc == SMLoc())
1182 ErrorLoc = IDLoc;
Jack Carterb4dbc172012-09-05 23:34:03 +00001183 }
1184
1185 return Error(ErrorLoc, "invalid operand for instruction");
1186 }
1187 case Match_MnemonicFail:
1188 return Error(IDLoc, "invalid instruction");
1189 }
Rafael Espindola870c4e92012-01-11 03:56:41 +00001190 return true;
1191}
1192
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001193void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1194 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1195 if (RegIndex == 1)
1196 Warning(Loc, "Used $at without \".set noat\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001197 else
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001198 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1199 Twine(RegIndex) + "\"");
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001200 }
1201}
1202
Jack Carter1ac53222013-02-20 23:11:17 +00001203int MipsAsmParser::matchCPURegisterName(StringRef Name) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001204 int CC;
Jack Carter1ac53222013-02-20 23:11:17 +00001205
Vladimir Medic4c299852013-11-06 11:27:05 +00001206 CC = StringSwitch<unsigned>(Name)
1207 .Case("zero", 0)
Daniel Sandersb1d7e532014-03-25 11:16:03 +00001208 .Case("at", 1)
Vladimir Medic4c299852013-11-06 11:27:05 +00001209 .Case("a0", 4)
1210 .Case("a1", 5)
1211 .Case("a2", 6)
1212 .Case("a3", 7)
1213 .Case("v0", 2)
1214 .Case("v1", 3)
1215 .Case("s0", 16)
1216 .Case("s1", 17)
1217 .Case("s2", 18)
1218 .Case("s3", 19)
1219 .Case("s4", 20)
1220 .Case("s5", 21)
1221 .Case("s6", 22)
1222 .Case("s7", 23)
1223 .Case("k0", 26)
1224 .Case("k1", 27)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001225 .Case("gp", 28)
Vladimir Medic4c299852013-11-06 11:27:05 +00001226 .Case("sp", 29)
1227 .Case("fp", 30)
Daniel Sanders85f482b2014-03-26 11:05:24 +00001228 .Case("s8", 30)
Vladimir Medic4c299852013-11-06 11:27:05 +00001229 .Case("ra", 31)
1230 .Case("t0", 8)
1231 .Case("t1", 9)
1232 .Case("t2", 10)
1233 .Case("t3", 11)
1234 .Case("t4", 12)
1235 .Case("t5", 13)
1236 .Case("t6", 14)
1237 .Case("t7", 15)
1238 .Case("t8", 24)
1239 .Case("t9", 25)
1240 .Default(-1);
Jack Carter1ac53222013-02-20 23:11:17 +00001241
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001242 if (isN32() || isN64()) {
1243 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1244 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1245 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1246 if (8 <= CC && CC <= 11)
1247 CC += 4;
Jack Carter1ac53222013-02-20 23:11:17 +00001248
Daniel Sandersa4b0c742014-03-26 11:39:07 +00001249 if (CC == -1)
1250 CC = StringSwitch<unsigned>(Name)
1251 .Case("a4", 8)
1252 .Case("a5", 9)
1253 .Case("a6", 10)
1254 .Case("a7", 11)
1255 .Case("kt0", 26)
1256 .Case("kt1", 27)
1257 .Default(-1);
1258 }
Jack Carter1ac53222013-02-20 23:11:17 +00001259
1260 return CC;
1261}
Jack Carterd0bd6422013-04-18 00:41:53 +00001262
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001263int MipsAsmParser::matchFPURegisterName(StringRef Name) {
Jack Carterb4dbc172012-09-05 23:34:03 +00001264
Jack Cartera63b16a2012-09-07 00:23:42 +00001265 if (Name[0] == 'f') {
1266 StringRef NumString = Name.substr(1);
1267 unsigned IntVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001268 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001269 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001270 if (IntVal > 31) // Maximum index for fpu register.
Jack Cartera63b16a2012-09-07 00:23:42 +00001271 return -1;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001272 return IntVal;
1273 }
1274 return -1;
1275}
Jack Cartera63b16a2012-09-07 00:23:42 +00001276
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001277int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1278
1279 if (Name.startswith("fcc")) {
1280 StringRef NumString = Name.substr(3);
1281 unsigned IntVal;
1282 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001283 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001284 if (IntVal > 7) // There are only 8 fcc registers.
1285 return -1;
1286 return IntVal;
1287 }
1288 return -1;
1289}
1290
1291int MipsAsmParser::matchACRegisterName(StringRef Name) {
1292
Akira Hatanaka274d24c2013-08-14 01:15:52 +00001293 if (Name.startswith("ac")) {
1294 StringRef NumString = Name.substr(2);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001295 unsigned IntVal;
1296 if (NumString.getAsInteger(10, IntVal))
Vladimir Medic4c299852013-11-06 11:27:05 +00001297 return -1; // This is not an integer.
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001298 if (IntVal > 3) // There are only 3 acc registers.
1299 return -1;
1300 return IntVal;
Jack Cartera63b16a2012-09-07 00:23:42 +00001301 }
Jack Carterb4dbc172012-09-05 23:34:03 +00001302 return -1;
1303}
Jack Carterd0bd6422013-04-18 00:41:53 +00001304
Jack Carter5dc8ac92013-09-25 23:50:44 +00001305int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1306 unsigned IntVal;
1307
1308 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1309 return -1;
1310
1311 if (IntVal > 31)
1312 return -1;
1313
1314 return IntVal;
1315}
1316
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001317int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1318 int CC;
1319
1320 CC = StringSwitch<unsigned>(Name)
Vladimir Medic4c299852013-11-06 11:27:05 +00001321 .Case("msair", 0)
1322 .Case("msacsr", 1)
1323 .Case("msaaccess", 2)
1324 .Case("msasave", 3)
1325 .Case("msamodify", 4)
1326 .Case("msarequest", 5)
1327 .Case("msamap", 6)
1328 .Case("msaunmap", 7)
1329 .Default(-1);
Matheus Almeidaa591fdc2013-10-21 12:26:50 +00001330
1331 return CC;
1332}
1333
Jack Carter0b744b32012-10-04 02:29:46 +00001334bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1335 if (Reg > 31)
1336 return false;
1337
1338 aTReg = Reg;
1339 return true;
1340}
1341
Daniel Sandersd89b1362014-03-24 16:48:01 +00001342int MipsAsmParser::getATReg() {
1343 int AT = Options.getATRegNum();
1344 if (AT == 0)
1345 TokError("Pseudo instruction requires $at, which is not available");
1346 return AT;
1347}
Jack Carter0b744b32012-10-04 02:29:46 +00001348
Jack Carterd0bd6422013-04-18 00:41:53 +00001349unsigned MipsAsmParser::getReg(int RC, int RegNo) {
Bill Wendlingbc07a892013-06-18 07:20:20 +00001350 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
Jack Carterb4dbc172012-09-05 23:34:03 +00001351}
1352
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001353unsigned MipsAsmParser::getGPR(int RegNo) {
Daniel Sanders5e94e682014-03-27 16:42:17 +00001354 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1355 RegNo);
Daniel Sanders5bce5f62014-03-27 13:52:53 +00001356}
1357
Jack Carter873c7242013-01-12 01:03:14 +00001358int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001359 if (RegNum >
Daniel Sanders64cf5a42014-03-27 15:00:44 +00001360 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
Jack Carterb4dbc172012-09-05 23:34:03 +00001361 return -1;
1362
Jack Carter873c7242013-01-12 01:03:14 +00001363 return getReg(RegClass, RegNum);
Jack Carterb4dbc172012-09-05 23:34:03 +00001364}
1365
Vladimir Medic4c299852013-11-06 11:27:05 +00001366bool
1367MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1368 StringRef Mnemonic) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001369 DEBUG(dbgs() << "ParseOperand\n");
1370
Jack Carter30a59822012-10-04 04:03:53 +00001371 // Check if the current operand has a custom associated parser, if so, try to
1372 // custom parse the operand, or fallback to the general approach.
Jack Carterb4dbc172012-09-05 23:34:03 +00001373 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1374 if (ResTy == MatchOperand_Success)
1375 return false;
1376 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1377 // there was a match, but an error occurred, in which case, just return that
1378 // the operand parsing failed.
1379 if (ResTy == MatchOperand_ParseFail)
1380 return true;
1381
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001382 DEBUG(dbgs() << ".. Generic Parser\n");
1383
Jack Carterb4dbc172012-09-05 23:34:03 +00001384 switch (getLexer().getKind()) {
1385 default:
1386 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1387 return true;
1388 case AsmToken::Dollar: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001389 // Parse the register.
Jack Carterb4dbc172012-09-05 23:34:03 +00001390 SMLoc S = Parser.getTok().getLoc();
Jack Carterb4dbc172012-09-05 23:34:03 +00001391
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001392 // Almost all registers have been parsed by custom parsers. There is only
1393 // one exception to this. $zero (and it's alias $0) will reach this point
1394 // for div, divu, and similar instructions because it is not an operand
1395 // to the instruction definition but an explicit register. Special case
1396 // this situation for now.
1397 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
Jack Carterb4dbc172012-09-05 23:34:03 +00001398 return false;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001399
Jack Carterd0bd6422013-04-18 00:41:53 +00001400 // Maybe it is a symbol reference.
Jack Carterb4dbc172012-09-05 23:34:03 +00001401 StringRef Identifier;
Jim Grosbachd2037eb2013-02-20 22:21:35 +00001402 if (Parser.parseIdentifier(Identifier))
Jack Carterb4dbc172012-09-05 23:34:03 +00001403 return true;
1404
Jack Carter873c7242013-01-12 01:03:14 +00001405 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Benjamin Kramerfa530572012-09-07 09:47:42 +00001406 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
Jack Carterd0bd6422013-04-18 00:41:53 +00001407 // Otherwise create a symbol reference.
Vladimir Medic4c299852013-11-06 11:27:05 +00001408 const MCExpr *Res =
1409 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
Jack Carterb4dbc172012-09-05 23:34:03 +00001410
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001411 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001412 return false;
1413 }
Vladimir Medic4c299852013-11-06 11:27:05 +00001414 // Else drop to expression parsing.
Jack Carterb4dbc172012-09-05 23:34:03 +00001415 case AsmToken::LParen:
1416 case AsmToken::Minus:
1417 case AsmToken::Plus:
1418 case AsmToken::Integer:
1419 case AsmToken::String: {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001420 DEBUG(dbgs() << ".. generic integer\n");
1421 OperandMatchResultTy ResTy = ParseImm(Operands);
1422 return ResTy != MatchOperand_Success;
Jack Carterb4dbc172012-09-05 23:34:03 +00001423 }
Jack Carterdc1e35d2012-09-06 20:00:02 +00001424 case AsmToken::Percent: {
Jack Carterd0bd6422013-04-18 00:41:53 +00001425 // It is a symbol reference or constant expression.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001426 const MCExpr *IdVal;
Jack Carterd0bd6422013-04-18 00:41:53 +00001427 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
Jack Carter873c7242013-01-12 01:03:14 +00001428 if (parseRelocOperand(IdVal))
Jack Carterdc1e35d2012-09-06 20:00:02 +00001429 return true;
1430
Jack Carter873c7242013-01-12 01:03:14 +00001431 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1432
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001433 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterdc1e35d2012-09-06 20:00:02 +00001434 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00001435 } // case AsmToken::Percent
1436 } // switch(getLexer().getKind())
Rafael Espindola870c4e92012-01-11 03:56:41 +00001437 return true;
1438}
1439
Vladimir Medic4c299852013-11-06 11:27:05 +00001440const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
Jack Carterb5cf5902013-04-17 00:18:04 +00001441 StringRef RelocStr) {
Jack Carterb5cf5902013-04-17 00:18:04 +00001442 const MCExpr *Res;
Jack Carterd0bd6422013-04-18 00:41:53 +00001443 // Check the type of the expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001444 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001445 // It's a constant, evaluate lo or hi value.
Jack Carterb5cf5902013-04-17 00:18:04 +00001446 if (RelocStr == "lo") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001447 short Val = MCE->getValue();
1448 Res = MCConstantExpr::Create(Val, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001449 } else if (RelocStr == "hi") {
Jack Carter9e65aa32013-03-22 00:05:30 +00001450 int Val = MCE->getValue();
Jack Carterdc463382013-02-21 02:09:31 +00001451 int LoSign = Val & 0x8000;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001452 Val = (Val & 0xffff0000) >> 16;
Jack Carter9e65aa32013-03-22 00:05:30 +00001453 // Lower part is treated as a signed int, so if it is negative
Jack Carterd0bd6422013-04-18 00:41:53 +00001454 // we must add 1 to the hi part to compensate.
Jack Carterdc463382013-02-21 02:09:31 +00001455 if (LoSign)
1456 Val++;
Jack Carter9e65aa32013-03-22 00:05:30 +00001457 Res = MCConstantExpr::Create(Val, getContext());
Evgeniy Stepanov3d8ab192013-04-17 06:45:11 +00001458 } else {
1459 llvm_unreachable("Invalid RelocStr value");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001460 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001461 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001462 }
1463
Jack Carterb5cf5902013-04-17 00:18:04 +00001464 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001465 // It's a symbol, create a symbolic expression from the symbol.
Benjamin Kramerfa530572012-09-07 09:47:42 +00001466 StringRef Symbol = MSRE->getSymbol().getName();
Jack Carterb5cf5902013-04-17 00:18:04 +00001467 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
Jack Carterd0bd6422013-04-18 00:41:53 +00001468 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
Jack Carterb5cf5902013-04-17 00:18:04 +00001469 return Res;
1470 }
1471
1472 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
Petar Jovanovica5da5882014-02-04 18:41:57 +00001473 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1474
1475 // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
1476 if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
1477 && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
1478 || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
1479 // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
1480 if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
1481 return MipsMCExpr::CreateHi(Expr, getContext());
1482 return MipsMCExpr::CreateLo(Expr, getContext());
1483 }
1484
Jack Carterd0bd6422013-04-18 00:41:53 +00001485 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1486 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Jack Carterb5cf5902013-04-17 00:18:04 +00001487 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1488 return Res;
1489 }
1490
1491 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001492 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1493 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1494 return Res;
Jack Carterb5cf5902013-04-17 00:18:04 +00001495 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001496 // Just return the original expression.
Jack Carterb5cf5902013-04-17 00:18:04 +00001497 return Expr;
1498}
1499
1500bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1501
1502 switch (Expr->getKind()) {
1503 case MCExpr::Constant:
1504 return true;
1505 case MCExpr::SymbolRef:
1506 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1507 case MCExpr::Binary:
1508 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1509 if (!isEvaluated(BE->getLHS()))
1510 return false;
1511 return isEvaluated(BE->getRHS());
1512 }
1513 case MCExpr::Unary:
1514 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
Petar Jovanovica5da5882014-02-04 18:41:57 +00001515 case MCExpr::Target:
1516 return true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001517 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001518 return false;
Jack Carterb5cf5902013-04-17 00:18:04 +00001519}
Jack Carterd0bd6422013-04-18 00:41:53 +00001520
Jack Carterb5cf5902013-04-17 00:18:04 +00001521bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001522 Parser.Lex(); // Eat the % token.
Jack Carterd0bd6422013-04-18 00:41:53 +00001523 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
Jack Carterb5cf5902013-04-17 00:18:04 +00001524 if (Tok.isNot(AsmToken::Identifier))
1525 return true;
1526
1527 std::string Str = Tok.getIdentifier().str();
1528
Jack Carterd0bd6422013-04-18 00:41:53 +00001529 Parser.Lex(); // Eat the identifier.
1530 // Now make an expression from the rest of the operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001531 const MCExpr *IdVal;
1532 SMLoc EndLoc;
1533
1534 if (getLexer().getKind() == AsmToken::LParen) {
1535 while (1) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001536 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001537 if (getLexer().getKind() == AsmToken::Percent) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001538 Parser.Lex(); // Eat the % token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001539 const AsmToken &nextTok = Parser.getTok();
1540 if (nextTok.isNot(AsmToken::Identifier))
1541 return true;
1542 Str += "(%";
1543 Str += nextTok.getIdentifier();
Jack Carterd0bd6422013-04-18 00:41:53 +00001544 Parser.Lex(); // Eat the identifier.
Jack Carterb5cf5902013-04-17 00:18:04 +00001545 if (getLexer().getKind() != AsmToken::LParen)
1546 return true;
1547 } else
1548 break;
1549 }
Jack Carterd0bd6422013-04-18 00:41:53 +00001550 if (getParser().parseParenExpression(IdVal, EndLoc))
Jack Carterb5cf5902013-04-17 00:18:04 +00001551 return true;
1552
1553 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterd0bd6422013-04-18 00:41:53 +00001554 Parser.Lex(); // Eat the ')' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001555
1556 } else
Jack Carterd0bd6422013-04-18 00:41:53 +00001557 return true; // Parenthesis must follow the relocation operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001558
Jack Carterd0bd6422013-04-18 00:41:53 +00001559 Res = evaluateRelocExpr(IdVal, Str);
Jack Carterb5cf5902013-04-17 00:18:04 +00001560 return false;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001561}
1562
Jack Carterb4dbc172012-09-05 23:34:03 +00001563bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1564 SMLoc &EndLoc) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001565 SmallVector<MCParsedAsmOperand *, 1> Operands;
1566 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1567 if (ResTy == MatchOperand_Success) {
1568 assert(Operands.size() == 1);
1569 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
1570 StartLoc = Operand.getStartLoc();
1571 EndLoc = Operand.getEndLoc();
1572
1573 // AFAIK, we only support numeric registers and named GPR's in CFI
1574 // directives.
1575 // Don't worry about eating tokens before failing. Using an unrecognised
1576 // register is a parse error.
1577 if (Operand.isGPRAsmReg()) {
1578 // Resolve to GPR32 or GPR64 appropriately.
1579 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1580 }
1581
1582 return (RegNo == (unsigned)-1);
1583 }
1584
1585 assert(Operands.size() == 0);
Vladimir Medic4c299852013-11-06 11:27:05 +00001586 return (RegNo == (unsigned)-1);
Jack Carterb4dbc172012-09-05 23:34:03 +00001587}
1588
Jack Carterb5cf5902013-04-17 00:18:04 +00001589bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
Jack Carter873c7242013-01-12 01:03:14 +00001590 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001591 bool Result = true;
1592
1593 while (getLexer().getKind() == AsmToken::LParen)
1594 Parser.Lex();
Jack Carter873c7242013-01-12 01:03:14 +00001595
Jack Carterd0bd6422013-04-18 00:41:53 +00001596 switch (getLexer().getKind()) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001597 default:
1598 return true;
Jack Carter9e65aa32013-03-22 00:05:30 +00001599 case AsmToken::Identifier:
Jack Carterb5cf5902013-04-17 00:18:04 +00001600 case AsmToken::LParen:
Jack Carterdc1e35d2012-09-06 20:00:02 +00001601 case AsmToken::Integer:
1602 case AsmToken::Minus:
1603 case AsmToken::Plus:
Jack Carterb5cf5902013-04-17 00:18:04 +00001604 if (isParenExpr)
Jack Carterd0bd6422013-04-18 00:41:53 +00001605 Result = getParser().parseParenExpression(Res, S);
Jack Carterb5cf5902013-04-17 00:18:04 +00001606 else
1607 Result = (getParser().parseExpression(Res));
Jack Carterd0bd6422013-04-18 00:41:53 +00001608 while (getLexer().getKind() == AsmToken::RParen)
Jack Carterb5cf5902013-04-17 00:18:04 +00001609 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00001610 break;
Jack Carter873c7242013-01-12 01:03:14 +00001611 case AsmToken::Percent:
Jack Carterb5cf5902013-04-17 00:18:04 +00001612 Result = parseRelocOperand(Res);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001613 }
Jack Carterb5cf5902013-04-17 00:18:04 +00001614 return Result;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001615}
1616
Jack Carterb4dbc172012-09-05 23:34:03 +00001617MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
Vladimir Medic4c299852013-11-06 11:27:05 +00001618 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001619 DEBUG(dbgs() << "parseMemOperand\n");
Jack Carterdc1e35d2012-09-06 20:00:02 +00001620 const MCExpr *IdVal = 0;
Jack Carter873c7242013-01-12 01:03:14 +00001621 SMLoc S;
Jack Carterb5cf5902013-04-17 00:18:04 +00001622 bool isParenExpr = false;
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001623 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
Jack Carterd0bd6422013-04-18 00:41:53 +00001624 // First operand is the offset.
Jack Carter873c7242013-01-12 01:03:14 +00001625 S = Parser.getTok().getLoc();
Jack Carterdc1e35d2012-09-06 20:00:02 +00001626
Jack Carterb5cf5902013-04-17 00:18:04 +00001627 if (getLexer().getKind() == AsmToken::LParen) {
1628 Parser.Lex();
1629 isParenExpr = true;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001630 }
1631
Jack Carterb5cf5902013-04-17 00:18:04 +00001632 if (getLexer().getKind() != AsmToken::Dollar) {
Jack Carterd0bd6422013-04-18 00:41:53 +00001633 if (parseMemOffset(IdVal, isParenExpr))
Jack Carterb5cf5902013-04-17 00:18:04 +00001634 return MatchOperand_ParseFail;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001635
Jack Carterd0bd6422013-04-18 00:41:53 +00001636 const AsmToken &Tok = Parser.getTok(); // Get the next token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001637 if (Tok.isNot(AsmToken::LParen)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001638 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
Jack Carterb5cf5902013-04-17 00:18:04 +00001639 if (Mnemonic->getToken() == "la") {
Vladimir Medic4c299852013-11-06 11:27:05 +00001640 SMLoc E =
1641 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001642 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001643 return MatchOperand_Success;
1644 }
1645 if (Tok.is(AsmToken::EndOfStatement)) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001646 SMLoc E =
1647 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jack Carterb5cf5902013-04-17 00:18:04 +00001648
Jack Carterd0bd6422013-04-18 00:41:53 +00001649 // Zero register assumed, add a memory operand with ZERO as its base.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001650 MipsOperand *Base = MipsOperand::CreateGPRReg(
1651 0, getContext().getRegisterInfo(), S, E, *this);
1652 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
Jack Carterb5cf5902013-04-17 00:18:04 +00001653 return MatchOperand_Success;
1654 }
1655 Error(Parser.getTok().getLoc(), "'(' expected");
1656 return MatchOperand_ParseFail;
1657 }
1658
Jack Carterd0bd6422013-04-18 00:41:53 +00001659 Parser.Lex(); // Eat the '(' token.
Jack Carterb5cf5902013-04-17 00:18:04 +00001660 }
1661
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001662 Res = ParseAnyRegister(Operands);
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001663 if (Res != MatchOperand_Success)
1664 return Res;
Jack Carterdc1e35d2012-09-06 20:00:02 +00001665
Vladimir Medic27c87ea2013-08-13 13:07:09 +00001666 if (Parser.getTok().isNot(AsmToken::RParen)) {
Jack Carterdc1e35d2012-09-06 20:00:02 +00001667 Error(Parser.getTok().getLoc(), "')' expected");
1668 return MatchOperand_ParseFail;
1669 }
1670
Jack Carter873c7242013-01-12 01:03:14 +00001671 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1672
Jack Carterd0bd6422013-04-18 00:41:53 +00001673 Parser.Lex(); // Eat the ')' token.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001674
1675 if (IdVal == 0)
1676 IdVal = MCConstantExpr::Create(0, getContext());
1677
Jack Carterd0bd6422013-04-18 00:41:53 +00001678 // Replace the register operand with the memory operand.
Vladimir Medic4c299852013-11-06 11:27:05 +00001679 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
Jack Carterd0bd6422013-04-18 00:41:53 +00001680 // Remove the register from the operands.
Jack Carterdc1e35d2012-09-06 20:00:02 +00001681 Operands.pop_back();
Jack Carterd0bd6422013-04-18 00:41:53 +00001682 // Add the memory operand.
Jack Carterb5cf5902013-04-17 00:18:04 +00001683 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1684 int64_t Imm;
1685 if (IdVal->EvaluateAsAbsolute(Imm))
1686 IdVal = MCConstantExpr::Create(Imm, getContext());
1687 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1688 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1689 getContext());
1690 }
1691
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001692 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00001693 return MatchOperand_Success;
1694}
1695
Daniel Sanderse34a1202014-03-31 18:51:43 +00001696bool MipsAsmParser::searchSymbolAlias(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001697 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sanderse34a1202014-03-31 18:51:43 +00001698
Jack Carterd76b2372013-03-21 21:44:16 +00001699 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1700 if (Sym) {
1701 SMLoc S = Parser.getTok().getLoc();
1702 const MCExpr *Expr;
1703 if (Sym->isVariable())
1704 Expr = Sym->getVariableValue();
1705 else
1706 return false;
1707 if (Expr->getKind() == MCExpr::SymbolRef) {
Vladimir Medic4c299852013-11-06 11:27:05 +00001708 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
Jack Carterd76b2372013-03-21 21:44:16 +00001709 const StringRef DefSymbol = Ref->getSymbol().getName();
1710 if (DefSymbol.startswith("$")) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001711 OperandMatchResultTy ResTy =
1712 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
Daniel Sanders09934572014-04-01 10:37:46 +00001713 if (ResTy == MatchOperand_Success) {
1714 Parser.Lex();
Jack Carterd76b2372013-03-21 21:44:16 +00001715 return true;
Daniel Sanders09934572014-04-01 10:37:46 +00001716 } else if (ResTy == MatchOperand_ParseFail)
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001717 llvm_unreachable("Should never ParseFail");
1718 return false;
Jack Carterd76b2372013-03-21 21:44:16 +00001719 }
1720 } else if (Expr->getKind() == MCExpr::Constant) {
1721 Parser.Lex();
Vladimir Medic4c299852013-11-06 11:27:05 +00001722 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1723 MipsOperand *op =
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001724 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
Jack Carterd76b2372013-03-21 21:44:16 +00001725 Operands.push_back(op);
1726 return true;
1727 }
1728 }
1729 return false;
1730}
Jack Carterd0bd6422013-04-18 00:41:53 +00001731
Jack Carter873c7242013-01-12 01:03:14 +00001732MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001733MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
1734 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
1735 SMLoc S) {
1736 int Index = matchCPURegisterName(Identifier);
1737 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001738 Operands.push_back(MipsOperand::CreateGPRReg(
1739 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1740 return MatchOperand_Success;
1741 }
1742
1743 Index = matchFPURegisterName(Identifier);
1744 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001745 Operands.push_back(MipsOperand::CreateFGRReg(
1746 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1747 return MatchOperand_Success;
1748 }
1749
1750 Index = matchFCCRegisterName(Identifier);
1751 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001752 Operands.push_back(MipsOperand::CreateFCCReg(
1753 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1754 return MatchOperand_Success;
1755 }
1756
1757 Index = matchACRegisterName(Identifier);
1758 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001759 Operands.push_back(MipsOperand::CreateACCReg(
1760 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1761 return MatchOperand_Success;
1762 }
1763
1764 Index = matchMSA128RegisterName(Identifier);
1765 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001766 Operands.push_back(MipsOperand::CreateMSA128Reg(
1767 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1768 return MatchOperand_Success;
1769 }
1770
1771 Index = matchMSA128CtrlRegisterName(Identifier);
1772 if (Index != -1) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001773 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1774 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1775 return MatchOperand_Success;
1776 }
1777
1778 return MatchOperand_NoMatch;
Jack Carter873c7242013-01-12 01:03:14 +00001779}
1780
1781MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001782MipsAsmParser::ParseAnyRegisterWithoutDollar(
1783 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
Daniel Sanders315386c2014-04-01 10:40:14 +00001784 auto Token = Parser.getLexer().peekTok(false);
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001785
1786 if (Token.is(AsmToken::Identifier)) {
1787 DEBUG(dbgs() << ".. identifier\n");
1788 StringRef Identifier = Token.getIdentifier();
Daniel Sanders09934572014-04-01 10:37:46 +00001789 OperandMatchResultTy ResTy =
1790 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
Daniel Sanders09934572014-04-01 10:37:46 +00001791 return ResTy;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001792 } else if (Token.is(AsmToken::Integer)) {
1793 DEBUG(dbgs() << ".. integer\n");
1794 Operands.push_back(MipsOperand::CreateNumericReg(
1795 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
1796 *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001797 return MatchOperand_Success;
1798 }
1799
1800 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
1801
1802 return MatchOperand_NoMatch;
1803}
1804
1805MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
1806 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1807 DEBUG(dbgs() << "ParseAnyRegister\n");
1808
1809 auto Token = Parser.getTok();
1810
1811 SMLoc S = Token.getLoc();
1812
1813 if (Token.isNot(AsmToken::Dollar)) {
1814 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
1815 if (Token.is(AsmToken::Identifier)) {
1816 if (searchSymbolAlias(Operands))
1817 return MatchOperand_Success;
1818 }
1819 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
1820 return MatchOperand_NoMatch;
1821 }
1822 DEBUG(dbgs() << ".. $\n");
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001823
1824 OperandMatchResultTy ResTy = ParseAnyRegisterWithoutDollar(Operands, S);
Daniel Sanders315386c2014-04-01 10:40:14 +00001825 if (ResTy == MatchOperand_Success) {
1826 Parser.Lex(); // $
1827 Parser.Lex(); // identifier
1828 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001829 return ResTy;
1830}
1831
1832MipsAsmParser::OperandMatchResultTy
1833MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1834 switch (getLexer().getKind()) {
1835 default:
1836 return MatchOperand_NoMatch;
1837 case AsmToken::LParen:
1838 case AsmToken::Minus:
1839 case AsmToken::Plus:
1840 case AsmToken::Integer:
1841 case AsmToken::String:
1842 break;
1843 }
1844
1845 const MCExpr *IdVal;
1846 SMLoc S = Parser.getTok().getLoc();
1847 if (getParser().parseExpression(IdVal))
1848 return MatchOperand_ParseFail;
1849
1850 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1851 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1852 return MatchOperand_Success;
1853}
1854
1855MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
1856 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1857 DEBUG(dbgs() << "ParseJumpTarget\n");
1858
1859 SMLoc S = getLexer().getLoc();
1860
1861 // Integers and expressions are acceptable
1862 OperandMatchResultTy ResTy = ParseImm(Operands);
1863 if (ResTy != MatchOperand_NoMatch)
1864 return ResTy;
1865
Daniel Sanders315386c2014-04-01 10:40:14 +00001866 // Registers are a valid target and have priority over symbols.
1867 ResTy = ParseAnyRegister(Operands);
1868 if (ResTy != MatchOperand_NoMatch)
1869 return ResTy;
1870
Daniel Sandersffd84362014-04-01 10:41:48 +00001871 const MCExpr *Expr = nullptr;
1872 if (Parser.parseExpression(Expr)) {
1873 // We have no way of knowing if a symbol was consumed so we must ParseFail
1874 return MatchOperand_ParseFail;
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001875 }
Daniel Sandersffd84362014-04-01 10:41:48 +00001876 Operands.push_back(
1877 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001878 return MatchOperand_Success;
Jack Carter873c7242013-01-12 01:03:14 +00001879}
1880
Vladimir Medic2b953d02013-10-01 09:48:56 +00001881MipsAsmParser::OperandMatchResultTy
Vladimir Medic4c299852013-11-06 11:27:05 +00001882MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Vladimir Medic2b953d02013-10-01 09:48:56 +00001883 const MCExpr *IdVal;
1884 // If the first token is '$' we may have register operand.
1885 if (Parser.getTok().is(AsmToken::Dollar))
1886 return MatchOperand_NoMatch;
1887 SMLoc S = Parser.getTok().getLoc();
1888 if (getParser().parseExpression(IdVal))
1889 return MatchOperand_ParseFail;
1890 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
Vladimir Medic4c299852013-11-06 11:27:05 +00001891 assert(MCE && "Unexpected MCExpr type.");
Vladimir Medic2b953d02013-10-01 09:48:56 +00001892 int64_t Val = MCE->getValue();
1893 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1894 Operands.push_back(MipsOperand::CreateImm(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001895 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
Vladimir Medic2b953d02013-10-01 09:48:56 +00001896 return MatchOperand_Success;
1897}
1898
Matheus Almeida779c5932013-11-18 12:32:49 +00001899MipsAsmParser::OperandMatchResultTy
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001900MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Matheus Almeida779c5932013-11-18 12:32:49 +00001901 switch (getLexer().getKind()) {
1902 default:
1903 return MatchOperand_NoMatch;
1904 case AsmToken::LParen:
1905 case AsmToken::Plus:
1906 case AsmToken::Minus:
1907 case AsmToken::Integer:
1908 break;
1909 }
1910
1911 const MCExpr *Expr;
1912 SMLoc S = Parser.getTok().getLoc();
1913
1914 if (getParser().parseExpression(Expr))
1915 return MatchOperand_ParseFail;
1916
1917 int64_t Val;
1918 if (!Expr->EvaluateAsAbsolute(Val)) {
1919 Error(S, "expected immediate value");
1920 return MatchOperand_ParseFail;
1921 }
1922
1923 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
1924 // and because the CPU always adds one to the immediate field, the allowed
1925 // range becomes 1..4. We'll only check the range here and will deal
1926 // with the addition/subtraction when actually decoding/encoding
1927 // the instruction.
1928 if (Val < 1 || Val > 4) {
1929 Error(S, "immediate not in range (1..4)");
1930 return MatchOperand_ParseFail;
1931 }
1932
Jack Carter3b2c96e2014-01-22 23:31:38 +00001933 Operands.push_back(
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001934 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
Matheus Almeida779c5932013-11-18 12:32:49 +00001935 return MatchOperand_Success;
1936}
1937
Jack Carterdc1e35d2012-09-06 20:00:02 +00001938MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1939
Vladimir Medic4c299852013-11-06 11:27:05 +00001940 MCSymbolRefExpr::VariantKind VK =
1941 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1942 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1943 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1944 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1945 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1946 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1947 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1948 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1949 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1950 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1951 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1952 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1953 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1954 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1955 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1956 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1957 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1958 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
Daniel Sandersa567da52014-03-31 15:15:02 +00001959 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
1960 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
1961 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
1962 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
1963 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
1964 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
Vladimir Medic4c299852013-11-06 11:27:05 +00001965 .Default(MCSymbolRefExpr::VK_None);
Jack Carterdc1e35d2012-09-06 20:00:02 +00001966
Daniel Sandersa567da52014-03-31 15:15:02 +00001967 assert (VK != MCSymbolRefExpr::VK_None);
1968
Jack Carterdc1e35d2012-09-06 20:00:02 +00001969 return VK;
1970}
Jack Cartera63b16a2012-09-07 00:23:42 +00001971
Daniel Sandersb50ccf82014-04-01 10:35:28 +00001972/// Sometimes (i.e. load/stores) the operand may be followed immediately by
1973/// either this.
1974/// ::= '(', register, ')'
1975/// handle it before we iterate so we don't get tripped up by the lack of
1976/// a comma.
1977bool MipsAsmParser::ParseParenSuffix(
1978 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1979 if (getLexer().is(AsmToken::LParen)) {
1980 Operands.push_back(
1981 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
1982 Parser.Lex();
1983 if (ParseOperand(Operands, Name)) {
1984 SMLoc Loc = getLexer().getLoc();
1985 Parser.eatToEndOfStatement();
1986 return Error(Loc, "unexpected token in argument list");
1987 }
1988 if (Parser.getTok().isNot(AsmToken::RParen)) {
1989 SMLoc Loc = getLexer().getLoc();
1990 Parser.eatToEndOfStatement();
1991 return Error(Loc, "unexpected token, expected ')'");
1992 }
1993 Operands.push_back(
1994 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
1995 Parser.Lex();
1996 }
1997 return false;
1998}
1999
2000/// Sometimes (i.e. in MSA) the operand may be followed immediately by
2001/// either one of these.
2002/// ::= '[', register, ']'
2003/// ::= '[', integer, ']'
2004/// handle it before we iterate so we don't get tripped up by the lack of
2005/// a comma.
2006bool MipsAsmParser::ParseBracketSuffix(
2007 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2008 if (getLexer().is(AsmToken::LBrac)) {
2009 Operands.push_back(
2010 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2011 Parser.Lex();
2012 if (ParseOperand(Operands, Name)) {
2013 SMLoc Loc = getLexer().getLoc();
2014 Parser.eatToEndOfStatement();
2015 return Error(Loc, "unexpected token in argument list");
2016 }
2017 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2018 SMLoc Loc = getLexer().getLoc();
2019 Parser.eatToEndOfStatement();
2020 return Error(Loc, "unexpected token, expected ']'");
2021 }
2022 Operands.push_back(
2023 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2024 Parser.Lex();
2025 }
2026 return false;
2027}
2028
Vladimir Medic4c299852013-11-06 11:27:05 +00002029bool MipsAsmParser::ParseInstruction(
2030 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2031 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002032 DEBUG(dbgs() << "ParseInstruction\n");
Vladimir Medic74593e62013-07-17 15:00:42 +00002033 // Check if we have valid mnemonic
Craig Topper690d8ea2013-07-24 07:33:14 +00002034 if (!mnemonicIsValid(Name, 0)) {
Vladimir Medic74593e62013-07-17 15:00:42 +00002035 Parser.eatToEndOfStatement();
2036 return Error(NameLoc, "Unknown instruction");
2037 }
Vladimir Medic64828a12013-07-16 10:07:14 +00002038 // First operand in MCInst is instruction mnemonic.
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002039 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
Jack Carterb4dbc172012-09-05 23:34:03 +00002040
2041 // Read the remaining operands.
2042 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2043 // Read the first operand.
Vladimir Medic64828a12013-07-16 10:07:14 +00002044 if (ParseOperand(Operands, Name)) {
Jack Carterb4dbc172012-09-05 23:34:03 +00002045 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002046 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002047 return Error(Loc, "unexpected token in argument list");
2048 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002049 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2050 return true;
2051 // AFAIK, parenthesis suffixes are never on the first operand
Jack Carterb4dbc172012-09-05 23:34:03 +00002052
Jack Carterd0bd6422013-04-18 00:41:53 +00002053 while (getLexer().is(AsmToken::Comma)) {
2054 Parser.Lex(); // Eat the comma.
Jack Carterb4dbc172012-09-05 23:34:03 +00002055 // Parse and remember the operand.
2056 if (ParseOperand(Operands, Name)) {
2057 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002058 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002059 return Error(Loc, "unexpected token in argument list");
2060 }
Daniel Sandersb50ccf82014-04-01 10:35:28 +00002061 // Parse bracket and parenthesis suffixes before we iterate
2062 if (getLexer().is(AsmToken::LBrac)) {
2063 if (ParseBracketSuffix(Name, Operands))
2064 return true;
2065 } else if (getLexer().is(AsmToken::LParen) &&
2066 ParseParenSuffix(Name, Operands))
2067 return true;
Jack Carterb4dbc172012-09-05 23:34:03 +00002068 }
2069 }
Jack Carterb4dbc172012-09-05 23:34:03 +00002070 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2071 SMLoc Loc = getLexer().getLoc();
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002072 Parser.eatToEndOfStatement();
Jack Carterb4dbc172012-09-05 23:34:03 +00002073 return Error(Loc, "unexpected token in argument list");
2074 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002075 Parser.Lex(); // Consume the EndOfStatement.
Jack Carterb4dbc172012-09-05 23:34:03 +00002076 return false;
Rafael Espindola870c4e92012-01-11 03:56:41 +00002077}
2078
Jack Carter0b744b32012-10-04 02:29:46 +00002079bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002080 SMLoc Loc = getLexer().getLoc();
2081 Parser.eatToEndOfStatement();
2082 return Error(Loc, ErrorMsg);
Jack Carter0b744b32012-10-04 02:29:46 +00002083}
2084
2085bool MipsAsmParser::parseSetNoAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002086 // Line should look like: ".set noat".
2087 // set at reg to 0.
Jack Carter99d2afe2012-10-05 23:55:28 +00002088 Options.setATReg(0);
Jack Carter0b744b32012-10-04 02:29:46 +00002089 // eat noat
2090 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002091 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002092 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2093 reportParseError("unexpected token in statement");
2094 return false;
2095 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002096 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002097 return false;
2098}
Jack Carterd0bd6422013-04-18 00:41:53 +00002099
Jack Carter0b744b32012-10-04 02:29:46 +00002100bool MipsAsmParser::parseSetAtDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002101 // Line can be .set at - defaults to $1
Jack Carter0b744b32012-10-04 02:29:46 +00002102 // or .set at=$reg
Jack Carter1ac53222013-02-20 23:11:17 +00002103 int AtRegNo;
Jack Carter0b744b32012-10-04 02:29:46 +00002104 getParser().Lex();
2105 if (getLexer().is(AsmToken::EndOfStatement)) {
Jack Carter99d2afe2012-10-05 23:55:28 +00002106 Options.setATReg(1);
Jack Carterd0bd6422013-04-18 00:41:53 +00002107 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002108 return false;
2109 } else if (getLexer().is(AsmToken::Equal)) {
Jack Carterd0bd6422013-04-18 00:41:53 +00002110 getParser().Lex(); // Eat the '='.
Jack Carter0b744b32012-10-04 02:29:46 +00002111 if (getLexer().isNot(AsmToken::Dollar)) {
2112 reportParseError("unexpected token in statement");
2113 return false;
2114 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002115 Parser.Lex(); // Eat the '$'.
Jack Carter1ac53222013-02-20 23:11:17 +00002116 const AsmToken &Reg = Parser.getTok();
2117 if (Reg.is(AsmToken::Identifier)) {
2118 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2119 } else if (Reg.is(AsmToken::Integer)) {
2120 AtRegNo = Reg.getIntVal();
2121 } else {
Jack Carter0b744b32012-10-04 02:29:46 +00002122 reportParseError("unexpected token in statement");
2123 return false;
2124 }
Jack Carter1ac53222013-02-20 23:11:17 +00002125
Daniel Sanders71a89d922014-03-25 13:01:06 +00002126 if (AtRegNo < 0 || AtRegNo > 31) {
Jack Carter1ac53222013-02-20 23:11:17 +00002127 reportParseError("unexpected token in statement");
2128 return false;
2129 }
2130
2131 if (!Options.setATReg(AtRegNo)) {
Jack Carter0b744b32012-10-04 02:29:46 +00002132 reportParseError("unexpected token in statement");
2133 return false;
2134 }
Jack Carterd0bd6422013-04-18 00:41:53 +00002135 getParser().Lex(); // Eat the register.
Jack Carter0b744b32012-10-04 02:29:46 +00002136
2137 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2138 reportParseError("unexpected token in statement");
2139 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002140 }
2141 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002142 return false;
2143 } else {
2144 reportParseError("unexpected token in statement");
2145 return false;
2146 }
2147}
2148
2149bool MipsAsmParser::parseSetReorderDirective() {
2150 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002151 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002152 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2153 reportParseError("unexpected token in statement");
2154 return false;
2155 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002156 Options.setReorder();
Matheus Almeida64459d22014-03-10 13:21:10 +00002157 getTargetStreamer().emitDirectiveSetReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002158 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002159 return false;
2160}
2161
2162bool MipsAsmParser::parseSetNoReorderDirective() {
Jack Carterd0bd6422013-04-18 00:41:53 +00002163 Parser.Lex();
2164 // If this is not the end of the statement, report an error.
2165 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2166 reportParseError("unexpected token in statement");
Jack Carter0b744b32012-10-04 02:29:46 +00002167 return false;
Jack Carterd0bd6422013-04-18 00:41:53 +00002168 }
2169 Options.setNoreorder();
Rafael Espindolacb1953f2014-01-26 06:57:13 +00002170 getTargetStreamer().emitDirectiveSetNoReorder();
Jack Carterd0bd6422013-04-18 00:41:53 +00002171 Parser.Lex(); // Consume the EndOfStatement.
2172 return false;
Jack Carter0b744b32012-10-04 02:29:46 +00002173}
2174
2175bool MipsAsmParser::parseSetMacroDirective() {
2176 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002177 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002178 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2179 reportParseError("unexpected token in statement");
2180 return false;
2181 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002182 Options.setMacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002183 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002184 return false;
2185}
2186
2187bool MipsAsmParser::parseSetNoMacroDirective() {
2188 Parser.Lex();
Jack Carterd0bd6422013-04-18 00:41:53 +00002189 // If this is not the end of the statement, report an error.
Jack Carter0b744b32012-10-04 02:29:46 +00002190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2191 reportParseError("`noreorder' must be set before `nomacro'");
2192 return false;
2193 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002194 if (Options.isReorder()) {
Jack Carter0b744b32012-10-04 02:29:46 +00002195 reportParseError("`noreorder' must be set before `nomacro'");
2196 return false;
2197 }
Jack Carter99d2afe2012-10-05 23:55:28 +00002198 Options.setNomacro();
Jack Carterd0bd6422013-04-18 00:41:53 +00002199 Parser.Lex(); // Consume the EndOfStatement.
Jack Carter0b744b32012-10-04 02:29:46 +00002200 return false;
2201}
Jack Carterd76b2372013-03-21 21:44:16 +00002202
Jack Carter39536722014-01-22 23:08:42 +00002203bool MipsAsmParser::parseSetNoMips16Directive() {
2204 Parser.Lex();
2205 // If this is not the end of the statement, report an error.
2206 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2207 reportParseError("unexpected token in statement");
2208 return false;
2209 }
2210 // For now do nothing.
2211 Parser.Lex(); // Consume the EndOfStatement.
2212 return false;
2213}
2214
Jack Carterd76b2372013-03-21 21:44:16 +00002215bool MipsAsmParser::parseSetAssignment() {
2216 StringRef Name;
2217 const MCExpr *Value;
2218
2219 if (Parser.parseIdentifier(Name))
2220 reportParseError("expected identifier after .set");
2221
2222 if (getLexer().isNot(AsmToken::Comma))
2223 return reportParseError("unexpected token in .set directive");
Jack Carterb5cf5902013-04-17 00:18:04 +00002224 Lex(); // Eat comma
Jack Carterd76b2372013-03-21 21:44:16 +00002225
Jack Carter3b2c96e2014-01-22 23:31:38 +00002226 if (Parser.parseExpression(Value))
Jack Carter02593002013-05-28 22:21:05 +00002227 return reportParseError("expected valid expression after comma");
Jack Carterd76b2372013-03-21 21:44:16 +00002228
Jack Carterd0bd6422013-04-18 00:41:53 +00002229 // Check if the Name already exists as a symbol.
Jack Carterd76b2372013-03-21 21:44:16 +00002230 MCSymbol *Sym = getContext().LookupSymbol(Name);
Jack Carterd0bd6422013-04-18 00:41:53 +00002231 if (Sym)
Jack Carterd76b2372013-03-21 21:44:16 +00002232 return reportParseError("symbol already defined");
Jack Carterd76b2372013-03-21 21:44:16 +00002233 Sym = getContext().GetOrCreateSymbol(Name);
2234 Sym->setVariableValue(Value);
2235
2236 return false;
2237}
Jack Carterd0bd6422013-04-18 00:41:53 +00002238
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002239bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2240 Parser.Lex();
2241 if (getLexer().isNot(AsmToken::EndOfStatement))
2242 return reportParseError("unexpected token in .set directive");
2243
2244 switch(Feature) {
2245 default: llvm_unreachable("Unimplemented feature");
2246 case Mips::FeatureDSP:
2247 setFeatureBits(Mips::FeatureDSP, "dsp");
2248 getTargetStreamer().emitDirectiveSetDsp();
2249 break;
2250 case Mips::FeatureMicroMips:
2251 getTargetStreamer().emitDirectiveSetMicroMips();
2252 break;
2253 case Mips::FeatureMips16:
2254 getTargetStreamer().emitDirectiveSetMips16();
2255 break;
2256 case Mips::FeatureMips32r2:
2257 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2258 getTargetStreamer().emitDirectiveSetMips32R2();
2259 break;
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002260 case Mips::FeatureMips64:
2261 setFeatureBits(Mips::FeatureMips64, "mips64");
2262 getTargetStreamer().emitDirectiveSetMips64();
2263 break;
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002264 case Mips::FeatureMips64r2:
2265 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2266 getTargetStreamer().emitDirectiveSetMips64R2();
2267 break;
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002268 }
2269 return false;
2270}
2271
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002272bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2273 if (!getLexer().is(AsmToken::Dollar))
2274 return false;
2275
2276 Parser.Lex();
2277
2278 const AsmToken &Reg = Parser.getTok();
2279 if (Reg.is(AsmToken::Identifier)) {
2280 RegNum = matchCPURegisterName(Reg.getIdentifier());
2281 } else if (Reg.is(AsmToken::Integer)) {
2282 RegNum = Reg.getIntVal();
2283 } else {
2284 return false;
2285 }
2286
2287 Parser.Lex();
2288 return true;
2289}
2290
2291bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2292 if (getLexer().isNot(AsmToken::Comma)) {
2293 SMLoc Loc = getLexer().getLoc();
2294 Parser.eatToEndOfStatement();
2295 return Error(Loc, ErrorStr);
2296 }
2297
2298 Parser.Lex(); // Eat the comma.
2299 return true;
2300}
2301
2302bool MipsAsmParser::parseDirectiveCPSetup() {
2303 unsigned FuncReg;
2304 unsigned Save;
2305 bool SaveIsReg = true;
2306
2307 if (!parseRegister(FuncReg))
2308 return reportParseError("expected register containing function address");
2309 FuncReg = getGPR(FuncReg);
2310
2311 if (!eatComma("expected comma parsing directive"))
2312 return true;
2313
2314 if (!parseRegister(Save)) {
2315 const AsmToken &Tok = Parser.getTok();
2316 if (Tok.is(AsmToken::Integer)) {
2317 Save = Tok.getIntVal();
2318 SaveIsReg = false;
2319 Parser.Lex();
2320 } else
2321 return reportParseError("expected save register or stack offset");
2322 } else
2323 Save = getGPR(Save);
2324
2325 if (!eatComma("expected comma parsing directive"))
2326 return true;
2327
2328 StringRef Name;
2329 if (Parser.parseIdentifier(Name))
2330 reportParseError("expected identifier");
2331 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2332 unsigned GPReg = getGPR(matchCPURegisterName("gp"));
2333
2334 // FIXME: The code below this point should be in the TargetStreamers.
2335 // Only N32 and N64 emit anything for .cpsetup
2336 // FIXME: We should only emit something for PIC mode too.
2337 if (!isN32() && !isN64())
2338 return false;
2339
2340 MCStreamer &TS = getStreamer();
2341 MCInst Inst;
2342 // Either store the old $gp in a register or on the stack
2343 if (SaveIsReg) {
2344 // move $save, $gpreg
2345 Inst.setOpcode(Mips::DADDu);
2346 Inst.addOperand(MCOperand::CreateReg(Save));
2347 Inst.addOperand(MCOperand::CreateReg(GPReg));
2348 Inst.addOperand(MCOperand::CreateReg(getGPR(0)));
2349 } else {
2350 // sd $gpreg, offset($sp)
2351 Inst.setOpcode(Mips::SD);
2352 Inst.addOperand(MCOperand::CreateReg(GPReg));
2353 Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp"))));
2354 Inst.addOperand(MCOperand::CreateImm(Save));
2355 }
2356 TS.EmitInstruction(Inst, STI);
2357 Inst.clear();
2358
2359 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2360 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI,
2361 getContext());
2362 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2363 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO,
2364 getContext());
2365 // lui $gp, %hi(%neg(%gp_rel(funcSym)))
2366 Inst.setOpcode(Mips::LUi);
2367 Inst.addOperand(MCOperand::CreateReg(GPReg));
2368 Inst.addOperand(MCOperand::CreateExpr(HiExpr));
2369 TS.EmitInstruction(Inst, STI);
2370 Inst.clear();
2371
2372 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
2373 Inst.setOpcode(Mips::ADDiu);
2374 Inst.addOperand(MCOperand::CreateReg(GPReg));
2375 Inst.addOperand(MCOperand::CreateReg(GPReg));
2376 Inst.addOperand(MCOperand::CreateExpr(LoExpr));
2377 TS.EmitInstruction(Inst, STI);
2378 Inst.clear();
2379
2380 // daddu $gp, $gp, $funcreg
2381 Inst.setOpcode(Mips::DADDu);
2382 Inst.addOperand(MCOperand::CreateReg(GPReg));
2383 Inst.addOperand(MCOperand::CreateReg(GPReg));
2384 Inst.addOperand(MCOperand::CreateReg(FuncReg));
2385 TS.EmitInstruction(Inst, STI);
2386 return false;
2387}
2388
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 Almeidafe1e39d2014-03-26 14:26:27 +00002415 return parseSetFeature(Mips::FeatureMicroMips);
Vladimir Medic615b26e2014-03-04 09:54:09 +00002416 } else if (Tok.getString() == "mips32r2") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +00002417 return parseSetFeature(Mips::FeatureMips32r2);
Matheus Almeida3b9c63d2014-03-26 15:14:32 +00002418 } else if (Tok.getString() == "mips64") {
2419 return parseSetFeature(Mips::FeatureMips64);
Matheus Almeidaa2cd0092014-03-26 14:52:22 +00002420 } else if (Tok.getString() == "mips64r2") {
2421 return parseSetFeature(Mips::FeatureMips64r2);
Vladimir Medic27c398e2014-03-05 11:05:09 +00002422 } else if (Tok.getString() == "dsp") {
Matheus Almeidafe1e39d2014-03-26 14:26:27 +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 Almeidaab5633b2014-03-26 15:44:18 +00002533 if (IDVal == ".dword") {
2534 parseDataDirective(8, DirectiveID.getLoc());
2535 return false;
2536 }
2537
Jack Carterd0bd6422013-04-18 00:41:53 +00002538 if (IDVal == ".ent") {
2539 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002540 Parser.Lex();
2541 return false;
2542 }
2543
Jack Carter07c818d2013-01-25 01:31:34 +00002544 if (IDVal == ".end") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002545 // Ignore this directive for now.
Jack Carterbe332172012-09-07 00:48:02 +00002546 Parser.Lex();
2547 return false;
2548 }
2549
Jack Carter07c818d2013-01-25 01:31:34 +00002550 if (IDVal == ".frame") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002551 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002552 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002553 return false;
2554 }
2555
Jack Carter07c818d2013-01-25 01:31:34 +00002556 if (IDVal == ".set") {
Jack Carter0b744b32012-10-04 02:29:46 +00002557 return parseDirectiveSet();
Jack Carterbe332172012-09-07 00:48:02 +00002558 }
2559
Jack Carter07c818d2013-01-25 01:31:34 +00002560 if (IDVal == ".fmask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002561 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002562 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002563 return false;
2564 }
2565
Jack Carter07c818d2013-01-25 01:31:34 +00002566 if (IDVal == ".mask") {
Jack Carterd0bd6422013-04-18 00:41:53 +00002567 // Ignore this directive for now.
Jim Grosbachd2037eb2013-02-20 22:21:35 +00002568 Parser.eatToEndOfStatement();
Jack Carterbe332172012-09-07 00:48:02 +00002569 return false;
2570 }
2571
Jack Carter07c818d2013-01-25 01:31:34 +00002572 if (IDVal == ".gpword") {
Vladimir Medic4c299852013-11-06 11:27:05 +00002573 parseDirectiveGpWord();
Jack Carterbe332172012-09-07 00:48:02 +00002574 return false;
2575 }
2576
Rafael Espindolab59fb732014-03-28 18:50:26 +00002577 if (IDVal == ".gpdword") {
Rafael Espindola2378d4c2014-03-31 14:15:07 +00002578 parseDirectiveGpDWord();
Rafael Espindolab59fb732014-03-28 18:50:26 +00002579 return false;
2580 }
2581
Jack Carter07c818d2013-01-25 01:31:34 +00002582 if (IDVal == ".word") {
Matheus Almeida3e2a7022014-03-26 15:24:36 +00002583 parseDataDirective(4, DirectiveID.getLoc());
Jack Carter07c818d2013-01-25 01:31:34 +00002584 return false;
2585 }
2586
Jack Carter0cd3c192014-01-06 23:27:31 +00002587 if (IDVal == ".option")
2588 return parseDirectiveOption();
2589
2590 if (IDVal == ".abicalls") {
2591 getTargetStreamer().emitDirectiveAbiCalls();
2592 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2593 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2594 // Clear line
2595 Parser.eatToEndOfStatement();
2596 }
2597 return false;
2598 }
2599
Daniel Sanders5bce5f62014-03-27 13:52:53 +00002600 if (IDVal == ".cpsetup")
2601 return parseDirectiveCPSetup();
2602
Rafael Espindola870c4e92012-01-11 03:56:41 +00002603 return true;
2604}
2605
Rafael Espindola870c4e92012-01-11 03:56:41 +00002606extern "C" void LLVMInitializeMipsAsmParser() {
2607 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2608 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2609 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2610 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2611}
Jack Carterb4dbc172012-09-05 23:34:03 +00002612
2613#define GET_REGISTER_MATCHER
2614#define GET_MATCHER_IMPLEMENTATION
2615#include "MipsGenAsmMatcher.inc"