blob: 6998383f08eb8afbdcfc11d66e6091f85e48a8b1 [file] [log] [blame]
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001//===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst instructions----===//
2//
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
10#define DEBUG_TYPE "mcasmparser"
11
12#include "Hexagon.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000013#include "HexagonTargetStreamer.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000014#include "MCTargetDesc/HexagonMCChecker.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000015#include "MCTargetDesc/HexagonMCELFStreamer.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000016#include "MCTargetDesc/HexagonMCExpr.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000017#include "MCTargetDesc/HexagonMCInstrInfo.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000018#include "MCTargetDesc/HexagonMCTargetDesc.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000019#include "MCTargetDesc/HexagonShuffler.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000020#include "llvm/ADT/SmallVector.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000021#include "llvm/ADT/STLExtras.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000022#include "llvm/ADT/StringExtras.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000023#include "llvm/ADT/StringRef.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000024#include "llvm/ADT/Twine.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000025#include "llvm/MC/MCAssembler.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000026#include "llvm/MC/MCContext.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000027#include "llvm/MC/MCDirectives.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000028#include "llvm/MC/MCELFStreamer.h"
29#include "llvm/MC/MCExpr.h"
30#include "llvm/MC/MCInst.h"
31#include "llvm/MC/MCParser/MCAsmLexer.h"
32#include "llvm/MC/MCParser/MCAsmParser.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000033#include "llvm/MC/MCParser/MCAsmParserExtension.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000034#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000035#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000036#include "llvm/MC/MCRegisterInfo.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000037#include "llvm/MC/MCSectionELF.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000038#include "llvm/MC/MCStreamer.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000039#include "llvm/MC/MCSubtargetInfo.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000040#include "llvm/MC/MCSymbol.h"
Colin LeMahieu5cb6eea2016-03-01 21:37:41 +000041#include "llvm/MC/MCValue.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000042#include "llvm/Support/Casting.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000043#include "llvm/Support/CommandLine.h"
44#include "llvm/Support/Debug.h"
45#include "llvm/Support/ELF.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000046#include "llvm/Support/ErrorHandling.h"
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +000047#include "llvm/Support/Format.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000048#include "llvm/Support/MathExtras.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000049#include "llvm/Support/raw_ostream.h"
Eugene Zelenko82085922016-12-13 22:13:50 +000050#include "llvm/Support/SMLoc.h"
51#include "llvm/Support/TargetRegistry.h"
52#include <algorithm>
53#include <cassert>
54#include <cctype>
55#include <cstddef>
56#include <cstdint>
57#include <memory>
58#include <string>
59#include <utility>
Colin LeMahieu7cd08922015-11-09 04:07:48 +000060
61using namespace llvm;
62
63static cl::opt<bool> EnableFutureRegs("mfuture-regs",
64 cl::desc("Enable future registers"));
65
66static cl::opt<bool> WarnMissingParenthesis("mwarn-missing-parenthesis",
67cl::desc("Warn for missing parenthesis around predicate registers"),
68cl::init(true));
69static cl::opt<bool> ErrorMissingParenthesis("merror-missing-parenthesis",
70cl::desc("Error for missing parenthesis around predicate registers"),
71cl::init(false));
72static cl::opt<bool> WarnSignedMismatch("mwarn-sign-mismatch",
73cl::desc("Warn for mismatching a signed and unsigned value"),
74cl::init(true));
75static cl::opt<bool> WarnNoncontigiousRegister("mwarn-noncontigious-register",
76cl::desc("Warn for register names that arent contigious"),
77cl::init(true));
78static cl::opt<bool> ErrorNoncontigiousRegister("merror-noncontigious-register",
79cl::desc("Error for register names that aren't contigious"),
80cl::init(false));
81
Colin LeMahieu7cd08922015-11-09 04:07:48 +000082namespace {
Eugene Zelenko82085922016-12-13 22:13:50 +000083
Colin LeMahieu7cd08922015-11-09 04:07:48 +000084struct HexagonOperand;
85
86class HexagonAsmParser : public MCTargetAsmParser {
87
88 HexagonTargetStreamer &getTargetStreamer() {
89 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
90 return static_cast<HexagonTargetStreamer &>(TS);
91 }
92
Colin LeMahieu7cd08922015-11-09 04:07:48 +000093 MCAsmParser &Parser;
94 MCAssembler *Assembler;
95 MCInstrInfo const &MCII;
96 MCInst MCB;
97 bool InBrackets;
98
99 MCAsmParser &getParser() const { return Parser; }
100 MCAssembler *getAssembler() const { return Assembler; }
101 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
102
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000103 bool equalIsAsmAssignment() override { return false; }
104 bool isLabel(AsmToken &Token) override;
105
106 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
107 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
108 bool ParseDirectiveFalign(unsigned Size, SMLoc L);
109
Eugene Zelenko82085922016-12-13 22:13:50 +0000110 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000111 bool ParseDirectiveSubsection(SMLoc L);
112 bool ParseDirectiveValue(unsigned Size, SMLoc L);
113 bool ParseDirectiveComm(bool IsLocal, SMLoc L);
114 bool RegisterMatchesArch(unsigned MatchNum) const;
115
116 bool matchBundleOptions();
117 bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
118 bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
119 void canonicalizeImmediates(MCInst &MCI);
120 bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
121 OperandVector &InstOperands, uint64_t &ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000122 bool MatchingInlineAsm);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000123
124 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
125 OperandVector &Operands, MCStreamer &Out,
Colin LeMahieu9ea507e2015-11-09 07:10:24 +0000126 uint64_t &ErrorInfo, bool MatchingInlineAsm) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000127
128 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind) override;
Nirav Dave2364748a2016-09-16 18:30:20 +0000129 bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000130 int processInstruction(MCInst &Inst, OperandVector const &Operands,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000131 SMLoc IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000132
133 // Check if we have an assembler and, if so, set the ELF e_header flags.
134 void chksetELFHeaderEFlags(unsigned flags) {
135 if (getAssembler())
136 getAssembler()->setELFHeaderEFlags(flags);
137 }
138
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +0000139 unsigned matchRegister(StringRef Name);
140
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000141/// @name Auto-generated Match Functions
142/// {
143
144#define GET_ASSEMBLER_HEADER
145#include "HexagonGenAsmMatcher.inc"
146
147 /// }
148
149public:
Akira Hatanakab11ef082015-11-14 06:35:56 +0000150 HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000151 const MCInstrInfo &MII, const MCTargetOptions &Options)
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000152 : MCTargetAsmParser(Options, _STI), Parser(_Parser),
Colin LeMahieuf0af6e52015-11-13 17:42:46 +0000153 MCII (MII), MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) {
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000154 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000155
Eugene Zelenko82085922016-12-13 22:13:50 +0000156 MCAsmParserExtension::Initialize(_Parser);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000157
Eugene Zelenko82085922016-12-13 22:13:50 +0000158 Assembler = nullptr;
159 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
160 if (!Parser.getStreamer().hasRawTextSupport()) {
161 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
162 Assembler = &MES->getAssembler();
163 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000164 }
165
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000166 bool splitIdentifier(OperandVector &Operands);
167 bool parseOperand(OperandVector &Operands);
168 bool parseInstruction(OperandVector &Operands);
169 bool implicitExpressionLocation(OperandVector &Operands);
170 bool parseExpressionOrOperand(OperandVector &Operands);
171 bool parseExpression(MCExpr const *& Expr);
Eugene Zelenko82085922016-12-13 22:13:50 +0000172
173 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
174 SMLoc NameLoc, OperandVector &Operands) override
Colin LeMahieu9ea507e2015-11-09 07:10:24 +0000175 {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000176 llvm_unreachable("Unimplemented");
177 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000178
Eugene Zelenko82085922016-12-13 22:13:50 +0000179 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
180 OperandVector &Operands) override;
181
182 bool ParseDirective(AsmToken DirectiveID) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000183};
184
185/// HexagonOperand - Instances of this class represent a parsed Hexagon machine
186/// instruction.
187struct HexagonOperand : public MCParsedAsmOperand {
188 enum KindTy { Token, Immediate, Register } Kind;
189
190 SMLoc StartLoc, EndLoc;
191
192 struct TokTy {
193 const char *Data;
194 unsigned Length;
195 };
196
197 struct RegTy {
198 unsigned RegNum;
199 };
200
201 struct ImmTy {
202 const MCExpr *Val;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000203 };
204
205 struct InstTy {
206 OperandVector *SubInsts;
207 };
208
209 union {
210 struct TokTy Tok;
211 struct RegTy Reg;
212 struct ImmTy Imm;
213 };
214
215 HexagonOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
216
217public:
218 HexagonOperand(const HexagonOperand &o) : MCParsedAsmOperand() {
219 Kind = o.Kind;
220 StartLoc = o.StartLoc;
221 EndLoc = o.EndLoc;
222 switch (Kind) {
223 case Register:
224 Reg = o.Reg;
225 break;
226 case Immediate:
227 Imm = o.Imm;
228 break;
229 case Token:
230 Tok = o.Tok;
231 break;
232 }
233 }
234
235 /// getStartLoc - Get the location of the first token of this operand.
Eugene Zelenko82085922016-12-13 22:13:50 +0000236 SMLoc getStartLoc() const override { return StartLoc; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000237
238 /// getEndLoc - Get the location of the last token of this operand.
Eugene Zelenko82085922016-12-13 22:13:50 +0000239 SMLoc getEndLoc() const override { return EndLoc; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000240
Eugene Zelenko82085922016-12-13 22:13:50 +0000241 unsigned getReg() const override {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000242 assert(Kind == Register && "Invalid access!");
243 return Reg.RegNum;
244 }
245
246 const MCExpr *getImm() const {
247 assert(Kind == Immediate && "Invalid access!");
248 return Imm.Val;
249 }
250
Eugene Zelenko82085922016-12-13 22:13:50 +0000251 bool isToken() const override { return Kind == Token; }
252 bool isImm() const override { return Kind == Immediate; }
253 bool isMem() const override { llvm_unreachable("No isMem"); }
254 bool isReg() const override { return Kind == Register; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000255
256 bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
257 bool isRelocatable, bool Extendable) const {
258 if (Kind == Immediate) {
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000259 const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000260 if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000261 return false;
262 int64_t Res;
263 if (myMCExpr->evaluateAsAbsolute(Res)) {
264 int bits = immBits + zeroBits;
265 // Field bit range is zerobits + bits
266 // zeroBits must be 0
267 if (Res & ((1 << zeroBits) - 1))
268 return false;
269 if (isSigned) {
270 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
271 return true;
272 } else {
273 if (bits == 64)
274 return true;
275 if (Res >= 0)
Eugene Zelenko82085922016-12-13 22:13:50 +0000276 return ((uint64_t)Res < (uint64_t)(1ULL << bits));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000277 else {
278 const int64_t high_bit_set = 1ULL << 63;
279 const uint64_t mask = (high_bit_set >> (63 - bits));
Eugene Zelenko82085922016-12-13 22:13:50 +0000280 return (((uint64_t)Res & mask) == mask);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000281 }
282 }
283 } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
284 return true;
285 else if (myMCExpr->getKind() == MCExpr::Binary ||
286 myMCExpr->getKind() == MCExpr::Unary)
287 return true;
288 }
289 return false;
290 }
291
292 bool isf32Ext() const { return false; }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000293 bool iss32_0Imm() const { return CheckImmRange(32, 0, true, true, false); }
Colin LeMahieuecef1d92016-02-16 20:38:17 +0000294 bool iss23_2Imm() const { return CheckImmRange(23, 2, true, true, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000295 bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
296 bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
297 bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
298 bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000299 bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
300 bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
301 bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
302 bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
303 bool iss4_6Imm() const { return CheckImmRange(4, 0, true, false, false); }
304 bool iss3_6Imm() const { return CheckImmRange(3, 0, true, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000305 bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000306
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000307 bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
308 bool isu32_0Imm() const { return CheckImmRange(32, 0, false, true, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000309 bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000310 bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
311 bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
312 bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
313 bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
314 bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000315 bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
316 bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
317 bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000318 bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
319 bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
320 bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
321 bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
322 bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
323 bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
324 bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
325 bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
326 bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
327 bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000328
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000329 bool ism6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
330 bool isn8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
Colin LeMahieu81707542016-12-05 04:29:00 +0000331 bool isn1Const() const {
332 if (!isImm())
333 return false;
334 int64_t Value;
335 if (!getImm()->evaluateAsAbsolute(Value))
336 return false;
337 return Value == -1;
338 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000339
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000340 bool iss16_0Ext() const { return CheckImmRange(16 + 26, 0, true, true, true); }
341 bool iss12_0Ext() const { return CheckImmRange(12 + 26, 0, true, true, true); }
342 bool iss10_0Ext() const { return CheckImmRange(10 + 26, 0, true, true, true); }
343 bool iss9_0Ext() const { return CheckImmRange(9 + 26, 0, true, true, true); }
344 bool iss8_0Ext() const { return CheckImmRange(8 + 26, 0, true, true, true); }
345 bool iss7_0Ext() const { return CheckImmRange(7 + 26, 0, true, true, true); }
346 bool iss6_0Ext() const { return CheckImmRange(6 + 26, 0, true, true, true); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000347 bool iss11_0Ext() const {
348 return CheckImmRange(11 + 26, 0, true, true, true);
349 }
350 bool iss11_1Ext() const {
351 return CheckImmRange(11 + 26, 1, true, true, true);
352 }
353 bool iss11_2Ext() const {
354 return CheckImmRange(11 + 26, 2, true, true, true);
355 }
356 bool iss11_3Ext() const {
357 return CheckImmRange(11 + 26, 3, true, true, true);
358 }
359
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000360 bool isu7_0Ext() const { return CheckImmRange(7 + 26, 0, false, true, true); }
361 bool isu8_0Ext() const { return CheckImmRange(8 + 26, 0, false, true, true); }
362 bool isu9_0Ext() const { return CheckImmRange(9 + 26, 0, false, true, true); }
363 bool isu10_0Ext() const { return CheckImmRange(10 + 26, 0, false, true, true); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000364 bool isu6_0Ext() const { return CheckImmRange(6 + 26, 0, false, true, true); }
365 bool isu6_1Ext() const { return CheckImmRange(6 + 26, 1, false, true, true); }
366 bool isu6_2Ext() const { return CheckImmRange(6 + 26, 2, false, true, true); }
367 bool isu6_3Ext() const { return CheckImmRange(6 + 26, 3, false, true, true); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000368 bool isu32_0MustExt() const { return isImm(); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000369
370 void addRegOperands(MCInst &Inst, unsigned N) const {
371 assert(N == 1 && "Invalid number of operands!");
372 Inst.addOperand(MCOperand::createReg(getReg()));
373 }
374
375 void addImmOperands(MCInst &Inst, unsigned N) const {
376 assert(N == 1 && "Invalid number of operands!");
377 Inst.addOperand(MCOperand::createExpr(getImm()));
378 }
379
380 void addSignedImmOperands(MCInst &Inst, unsigned N) const {
381 assert(N == 1 && "Invalid number of operands!");
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000382 HexagonMCExpr *Expr =
383 const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000384 int64_t Value;
385 if (!Expr->evaluateAsAbsolute(Value)) {
386 Inst.addOperand(MCOperand::createExpr(Expr));
387 return;
388 }
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000389 int64_t Extended = SignExtend64(Value, 32);
390 if ((Extended < 0) != (Value < 0))
391 Expr->setSignMismatch();
392 Inst.addOperand(MCOperand::createExpr(Expr));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000393 }
394
395 void addf32ExtOperands(MCInst &Inst, unsigned N) const {
396 addImmOperands(Inst, N);
397 }
398
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000399 void adds32_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000400 addSignedImmOperands(Inst, N);
401 }
Colin LeMahieuecef1d92016-02-16 20:38:17 +0000402 void adds23_2ImmOperands(MCInst &Inst, unsigned N) const {
403 addSignedImmOperands(Inst, N);
404 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000405 void adds8_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000406 addSignedImmOperands(Inst, N);
407 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000408 void adds8_0Imm64Operands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000409 addSignedImmOperands(Inst, N);
410 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000411 void adds6_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000412 addSignedImmOperands(Inst, N);
413 }
414 void adds4_0ImmOperands(MCInst &Inst, unsigned N) const {
415 addSignedImmOperands(Inst, N);
416 }
417 void adds4_1ImmOperands(MCInst &Inst, unsigned N) const {
418 addSignedImmOperands(Inst, N);
419 }
420 void adds4_2ImmOperands(MCInst &Inst, unsigned N) const {
421 addSignedImmOperands(Inst, N);
422 }
423 void adds4_3ImmOperands(MCInst &Inst, unsigned N) const {
424 addSignedImmOperands(Inst, N);
425 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000426 void adds3_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000427 addSignedImmOperands(Inst, N);
428 }
429
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000430 void addu64_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000431 addImmOperands(Inst, N);
432 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000433 void addu32_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000434 addImmOperands(Inst, N);
435 }
436 void addu26_6ImmOperands(MCInst &Inst, unsigned N) const {
437 addImmOperands(Inst, N);
438 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000439 void addu16_0ImmOperands(MCInst &Inst, unsigned N) const {
440 addImmOperands(Inst, N);
441 }
442 void addu16_1ImmOperands(MCInst &Inst, unsigned N) const {
443 addImmOperands(Inst, N);
444 }
445 void addu16_2ImmOperands(MCInst &Inst, unsigned N) const {
446 addImmOperands(Inst, N);
447 }
448 void addu16_3ImmOperands(MCInst &Inst, unsigned N) const {
449 addImmOperands(Inst, N);
450 }
451 void addu11_3ImmOperands(MCInst &Inst, unsigned N) const {
452 addImmOperands(Inst, N);
453 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000454 void addu10_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000455 addImmOperands(Inst, N);
456 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000457 void addu9_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000458 addImmOperands(Inst, N);
459 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000460 void addu8_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000461 addImmOperands(Inst, N);
462 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000463 void addu7_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000464 addImmOperands(Inst, N);
465 }
466 void addu6_0ImmOperands(MCInst &Inst, unsigned N) const {
467 addImmOperands(Inst, N);
468 }
469 void addu6_1ImmOperands(MCInst &Inst, unsigned N) const {
470 addImmOperands(Inst, N);
471 }
472 void addu6_2ImmOperands(MCInst &Inst, unsigned N) const {
473 addImmOperands(Inst, N);
474 }
475 void addu6_3ImmOperands(MCInst &Inst, unsigned N) const {
476 addImmOperands(Inst, N);
477 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000478 void addu5_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000479 addImmOperands(Inst, N);
480 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000481 void addu4_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000482 addImmOperands(Inst, N);
483 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000484 void addu3_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000485 addImmOperands(Inst, N);
486 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000487 void addu2_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000488 addImmOperands(Inst, N);
489 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000490 void addu1_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000491 addImmOperands(Inst, N);
492 }
493
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000494 void addm6_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000495 addImmOperands(Inst, N);
496 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000497 void addn8_0ImmOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000498 addImmOperands(Inst, N);
499 }
500
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000501 void adds16_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000502 addSignedImmOperands(Inst, N);
503 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000504 void adds12_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000505 addSignedImmOperands(Inst, N);
506 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000507 void adds10_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000508 addSignedImmOperands(Inst, N);
509 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000510 void adds9_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000511 addSignedImmOperands(Inst, N);
512 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000513 void adds8_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000514 addSignedImmOperands(Inst, N);
515 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000516 void adds6_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000517 addSignedImmOperands(Inst, N);
518 }
519 void adds11_0ExtOperands(MCInst &Inst, unsigned N) const {
520 addSignedImmOperands(Inst, N);
521 }
522 void adds11_1ExtOperands(MCInst &Inst, unsigned N) const {
523 addSignedImmOperands(Inst, N);
524 }
525 void adds11_2ExtOperands(MCInst &Inst, unsigned N) const {
526 addSignedImmOperands(Inst, N);
527 }
528 void adds11_3ExtOperands(MCInst &Inst, unsigned N) const {
529 addSignedImmOperands(Inst, N);
530 }
Colin LeMahieu81707542016-12-05 04:29:00 +0000531 void addn1ConstOperands(MCInst &Inst, unsigned N) const {
532 addImmOperands(Inst, N);
533 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000534
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000535 void addu7_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000536 addImmOperands(Inst, N);
537 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000538 void addu8_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000539 addImmOperands(Inst, N);
540 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000541 void addu9_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000542 addImmOperands(Inst, N);
543 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000544 void addu10_0ExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000545 addImmOperands(Inst, N);
546 }
547 void addu6_0ExtOperands(MCInst &Inst, unsigned N) const {
548 addImmOperands(Inst, N);
549 }
550 void addu6_1ExtOperands(MCInst &Inst, unsigned N) const {
551 addImmOperands(Inst, N);
552 }
553 void addu6_2ExtOperands(MCInst &Inst, unsigned N) const {
554 addImmOperands(Inst, N);
555 }
556 void addu6_3ExtOperands(MCInst &Inst, unsigned N) const {
557 addImmOperands(Inst, N);
558 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000559 void addu32_0MustExtOperands(MCInst &Inst, unsigned N) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000560 addImmOperands(Inst, N);
561 }
562
563 void adds4_6ImmOperands(MCInst &Inst, unsigned N) const {
564 assert(N == 1 && "Invalid number of operands!");
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000565 const MCConstantExpr *CE =
566 dyn_cast<MCConstantExpr>(&HexagonMCInstrInfo::getExpr(*getImm()));
Colin LeMahieu4c606e62015-12-04 15:48:45 +0000567 Inst.addOperand(MCOperand::createImm(CE->getValue() * 64));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000568 }
569
570 void adds3_6ImmOperands(MCInst &Inst, unsigned N) const {
571 assert(N == 1 && "Invalid number of operands!");
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000572 const MCConstantExpr *CE =
573 dyn_cast<MCConstantExpr>(&HexagonMCInstrInfo::getExpr(*getImm()));
Colin LeMahieu4c606e62015-12-04 15:48:45 +0000574 Inst.addOperand(MCOperand::createImm(CE->getValue() * 64));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000575 }
576
577 StringRef getToken() const {
578 assert(Kind == Token && "Invalid access!");
579 return StringRef(Tok.Data, Tok.Length);
580 }
581
Eugene Zelenko82085922016-12-13 22:13:50 +0000582 void print(raw_ostream &OS) const override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000583
584 static std::unique_ptr<HexagonOperand> CreateToken(StringRef Str, SMLoc S) {
585 HexagonOperand *Op = new HexagonOperand(Token);
586 Op->Tok.Data = Str.data();
587 Op->Tok.Length = Str.size();
588 Op->StartLoc = S;
589 Op->EndLoc = S;
590 return std::unique_ptr<HexagonOperand>(Op);
591 }
592
593 static std::unique_ptr<HexagonOperand> CreateReg(unsigned RegNum, SMLoc S,
594 SMLoc E) {
595 HexagonOperand *Op = new HexagonOperand(Register);
596 Op->Reg.RegNum = RegNum;
597 Op->StartLoc = S;
598 Op->EndLoc = E;
599 return std::unique_ptr<HexagonOperand>(Op);
600 }
601
602 static std::unique_ptr<HexagonOperand> CreateImm(const MCExpr *Val, SMLoc S,
603 SMLoc E) {
604 HexagonOperand *Op = new HexagonOperand(Immediate);
605 Op->Imm.Val = Val;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000606 Op->StartLoc = S;
607 Op->EndLoc = E;
608 return std::unique_ptr<HexagonOperand>(Op);
609 }
610};
611
Eugene Zelenko82085922016-12-13 22:13:50 +0000612} // end anonymous namespace
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000613
614void HexagonOperand::print(raw_ostream &OS) const {
615 switch (Kind) {
616 case Immediate:
617 getImm()->print(OS, nullptr);
618 break;
619 case Register:
620 OS << "<register R";
621 OS << getReg() << ">";
622 break;
623 case Token:
624 OS << "'" << getToken() << "'";
625 break;
626 }
627}
628
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000629bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
630 DEBUG(dbgs() << "Bundle:");
631 DEBUG(MCB.dump_pretty(dbgs()));
632 DEBUG(dbgs() << "--\n");
633
634 // Check the bundle for errors.
635 const MCRegisterInfo *RI = getContext().getRegisterInfo();
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000636 HexagonMCChecker Check(MCII, getSTI(), MCB, MCB, *RI);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000637
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000638 bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MCII, getSTI(),
639 getContext(), MCB,
640 &Check);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000641
Eugene Zelenko82085922016-12-13 22:13:50 +0000642 while (Check.getNextErrInfo()) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000643 unsigned Reg = Check.getErrRegister();
644 Twine R(RI->getName(Reg));
645
646 uint64_t Err = Check.getError();
647 if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
648 if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000649 return Error(
650 IDLoc,
651 "unconditional branch cannot precede another branch in packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000652
653 if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
654 HexagonMCErrInfo::CHECK_ERROR_NEWV & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000655 return Error(IDLoc, "register `" + R +
656 "' used with `.new' "
657 "but not validly modified in the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000658
659 if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000660 return Error(IDLoc, "register `" + R + "' modified more than once");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000661
662 if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000663 return Error(IDLoc, "cannot write to read-only register `" + R + "'");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000664
665 if (HexagonMCErrInfo::CHECK_ERROR_LOOP & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000666 return Error(IDLoc, "loop-setup and some branch instructions "
667 "cannot be in the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000668
669 if (HexagonMCErrInfo::CHECK_ERROR_ENDLOOP & Err) {
670 Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
Nirav Dave2364748a2016-09-16 18:30:20 +0000671 return Error(IDLoc,
672 "packet marked with `:endloop" + N + "' " +
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000673 "cannot contain instructions that modify register " +
674 "`" + R + "'");
675 }
676
677 if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000678 return Error(
679 IDLoc,
680 "instruction cannot appear in packet with other instructions");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000681
682 if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000683 return Error(IDLoc, "too many slots used in packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000684
685 if (Err & HexagonMCErrInfo::CHECK_ERROR_SHUFFLE) {
686 uint64_t Erm = Check.getShuffleError();
687
688 if (HexagonShuffler::SHUFFLE_ERROR_INVALID == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000689 return Error(IDLoc, "invalid instruction packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000690 else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000691 return Error(IDLoc, "invalid instruction packet: too many stores");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000692 else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000693 return Error(IDLoc, "invalid instruction packet: too many loads");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000694 else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000695 return Error(IDLoc, "too many branches in packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000696 else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000697 return Error(IDLoc, "invalid instruction packet: out of slots");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000698 else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000699 return Error(IDLoc, "invalid instruction packet: slot error");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000700 else if (HexagonShuffler::SHUFFLE_ERROR_ERRATA2 == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000701 return Error(IDLoc, "v60 packet violation");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000702 else if (HexagonShuffler::SHUFFLE_ERROR_STORE_LOAD_CONFLICT == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000703 return Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000704 else
Nirav Dave2364748a2016-09-16 18:30:20 +0000705 return Error(IDLoc, "unknown error in instruction packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000706 }
707 }
708
709 unsigned Warn = Check.getWarning();
710 if (Warn != HexagonMCErrInfo::CHECK_SUCCESS) {
711 if (HexagonMCErrInfo::CHECK_WARN_CURRENT & Warn)
712 Warning(IDLoc, "register `" + R + "' used with `.cur' "
713 "but not used in the same packet");
714 else if (HexagonMCErrInfo::CHECK_WARN_TEMPORARY & Warn)
715 Warning(IDLoc, "register `" + R + "' used with `.tmp' "
716 "but not used in the same packet");
717 }
718 }
719
720 if (CheckOk) {
721 MCB.setLoc(IDLoc);
722 if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
723 assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
724 assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
725 // Empty packets are valid yet aren't emitted
726 return false;
727 }
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000728 Out.EmitInstruction(MCB, getSTI());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000729 } else {
730 // If compounding and duplexing didn't reduce the size below
731 // 4 or less we have a packet that is too big.
732 if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
733 Error(IDLoc, "invalid instruction packet: out of slots");
734 return true; // Error
735 }
736 }
737
738 return false; // No error
739}
740
741bool HexagonAsmParser::matchBundleOptions() {
742 MCAsmParser &Parser = getParser();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000743 while (true) {
744 if (!Parser.getTok().is(AsmToken::Colon))
745 return false;
Nirav Davefd910412016-06-17 16:06:17 +0000746 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000747 StringRef Option = Parser.getTok().getString();
748 if (Option.compare_lower("endloop0") == 0)
749 HexagonMCInstrInfo::setInnerLoop(MCB);
750 else if (Option.compare_lower("endloop1") == 0)
751 HexagonMCInstrInfo::setOuterLoop(MCB);
752 else if (Option.compare_lower("mem_noshuf") == 0)
753 HexagonMCInstrInfo::setMemReorderDisabled(MCB);
754 else if (Option.compare_lower("mem_shuf") == 0)
755 HexagonMCInstrInfo::setMemStoreReorderEnabled(MCB);
756 else
757 return true;
Nirav Davefd910412016-06-17 16:06:17 +0000758 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000759 }
760}
761
762// For instruction aliases, immediates are generated rather than
763// MCConstantExpr. Convert them for uniform MCExpr.
764// Also check for signed/unsigned mismatches and warn
765void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
766 MCInst NewInst;
767 NewInst.setOpcode(MCI.getOpcode());
768 for (MCOperand &I : MCI)
769 if (I.isImm()) {
770 int64_t Value (I.getImm());
Colin LeMahieuc7b21242016-02-15 18:47:55 +0000771 NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000772 MCConstantExpr::create(Value, getContext()), getContext())));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000773 }
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000774 else {
775 if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
776 WarnSignedMismatch)
777 Warning (MCI.getLoc(), "Signed/Unsigned mismatch");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000778 NewInst.addOperand(I);
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000779 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000780 MCI = NewInst;
781}
782
783bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
784 OperandVector &InstOperands,
785 uint64_t &ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000786 bool MatchingInlineAsm) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000787 // Perform matching with tablegen asmmatcher generated function
788 int result =
789 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
790 if (result == Match_Success) {
791 MCI.setLoc(IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000792 canonicalizeImmediates(MCI);
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000793 result = processInstruction(MCI, InstOperands, IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000794
795 DEBUG(dbgs() << "Insn:");
796 DEBUG(MCI.dump_pretty(dbgs()));
797 DEBUG(dbgs() << "\n\n");
798
799 MCI.setLoc(IDLoc);
800 }
801
802 // Create instruction operand for bundle instruction
803 // Break this into a separate function Code here is less readable
804 // Think about how to get an instruction error to report correctly.
805 // SMLoc will return the "{"
806 switch (result) {
807 default:
808 break;
809 case Match_Success:
810 return false;
811 case Match_MissingFeature:
812 return Error(IDLoc, "invalid instruction");
813 case Match_MnemonicFail:
814 return Error(IDLoc, "unrecognized instruction");
815 case Match_InvalidOperand:
816 SMLoc ErrorLoc = IDLoc;
817 if (ErrorInfo != ~0U) {
818 if (ErrorInfo >= InstOperands.size())
819 return Error(IDLoc, "too few operands for instruction");
820
821 ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
822 ->getStartLoc();
823 if (ErrorLoc == SMLoc())
824 ErrorLoc = IDLoc;
825 }
826 return Error(ErrorLoc, "invalid operand for instruction");
827 }
828 llvm_unreachable("Implement any new match types added!");
829}
830
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000831bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
832 OperandVector &Operands,
833 MCStreamer &Out,
834 uint64_t &ErrorInfo,
835 bool MatchingInlineAsm) {
836 if (!InBrackets) {
837 MCB.clear();
838 MCB.addOperand(MCOperand::createImm(0));
839 }
840 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
841 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
842 assert(Operands.size() == 1 && "Brackets should be by themselves");
843 if (InBrackets) {
844 getParser().Error(IDLoc, "Already in a packet");
845 return true;
846 }
847 InBrackets = true;
848 return false;
849 }
850 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
851 assert(Operands.size() == 1 && "Brackets should be by themselves");
852 if (!InBrackets) {
853 getParser().Error(IDLoc, "Not in a packet");
854 return true;
855 }
856 InBrackets = false;
857 if (matchBundleOptions())
858 return true;
859 return finishBundle(IDLoc, Out);
860 }
861 MCInst *SubInst = new (getParser().getContext()) MCInst;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000862 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000863 MatchingInlineAsm))
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000864 return true;
865 HexagonMCInstrInfo::extendIfNeeded(
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000866 getParser().getContext(), MCII, MCB, *SubInst);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000867 MCB.addOperand(MCOperand::createInst(SubInst));
868 if (!InBrackets)
869 return finishBundle(IDLoc, Out);
870 return false;
871}
872
873/// ParseDirective parses the Hexagon specific directives
874bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
875 StringRef IDVal = DirectiveID.getIdentifier();
876 if ((IDVal.lower() == ".word") || (IDVal.lower() == ".4byte"))
877 return ParseDirectiveValue(4, DirectiveID.getLoc());
878 if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
879 IDVal.lower() == ".half")
880 return ParseDirectiveValue(2, DirectiveID.getLoc());
881 if (IDVal.lower() == ".falign")
882 return ParseDirectiveFalign(256, DirectiveID.getLoc());
883 if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
884 return ParseDirectiveComm(true, DirectiveID.getLoc());
885 if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
886 return ParseDirectiveComm(false, DirectiveID.getLoc());
887 if (IDVal.lower() == ".subsection")
888 return ParseDirectiveSubsection(DirectiveID.getLoc());
889
890 return true;
891}
892bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
Eugene Zelenko82085922016-12-13 22:13:50 +0000893 const MCExpr *Subsection = nullptr;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000894 int64_t Res;
895
896 assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
897 "Invalid subsection directive");
898 getParser().parseExpression(Subsection);
899
900 if (!Subsection->evaluateAsAbsolute(Res))
901 return Error(L, "Cannot evaluate subsection number");
902
903 if (getLexer().isNot(AsmToken::EndOfStatement))
904 return TokError("unexpected token in directive");
905
906 // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
907 // negative subsections together and in the same order but at the opposite
908 // end of the section. Only legacy hexagon-gcc created assembly code
909 // used negative subsections.
910 if ((Res < 0) && (Res > -8193))
Colin LeMahieuc7b21242016-02-15 18:47:55 +0000911 Subsection = HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000912 MCConstantExpr::create(8192 + Res, getContext()), getContext());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000913
914 getStreamer().SubSection(Subsection);
915 return false;
916}
917
918/// ::= .falign [expression]
919bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
920
921 int64_t MaxBytesToFill = 15;
922
Simon Pilgrim6ba672e2016-11-17 19:21:20 +0000923 // if there is an argument
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000924 if (getLexer().isNot(AsmToken::EndOfStatement)) {
925 const MCExpr *Value;
926 SMLoc ExprLoc = L;
927
928 // Make sure we have a number (false is returned if expression is a number)
Eugene Zelenko82085922016-12-13 22:13:50 +0000929 if (!getParser().parseExpression(Value)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000930 // Make sure this is a number that is in range
931 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
932 uint64_t IntValue = MCE->getValue();
933 if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
934 return Error(ExprLoc, "literal value out of range (256) for falign");
935 MaxBytesToFill = IntValue;
936 Lex();
937 } else {
938 return Error(ExprLoc, "not a valid expression for falign directive");
939 }
940 }
941
942 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
943 Lex();
944
945 return false;
946}
947
948/// ::= .word [ expression (, expression)* ]
949bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L) {
950 if (getLexer().isNot(AsmToken::EndOfStatement)) {
Eugene Zelenko82085922016-12-13 22:13:50 +0000951 while (true) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000952 const MCExpr *Value;
953 SMLoc ExprLoc = L;
954 if (getParser().parseExpression(Value))
955 return true;
956
957 // Special case constant expressions to match code generator.
958 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
959 assert(Size <= 8 && "Invalid size");
960 uint64_t IntValue = MCE->getValue();
961 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
962 return Error(ExprLoc, "literal value out of range for directive");
963 getStreamer().EmitIntValue(IntValue, Size);
964 } else
965 getStreamer().EmitValue(Value, Size);
966
967 if (getLexer().is(AsmToken::EndOfStatement))
968 break;
969
970 // FIXME: Improve diagnostic.
971 if (getLexer().isNot(AsmToken::Comma))
972 return TokError("unexpected token in directive");
973 Lex();
974 }
975 }
976
977 Lex();
978 return false;
979}
980
981// This is largely a copy of AsmParser's ParseDirectiveComm extended to
982// accept a 3rd argument, AccessAlignment which indicates the smallest
983// memory access made to the symbol, expressed in bytes. If no
984// AccessAlignment is specified it defaults to the Alignment Value.
985// Hexagon's .lcomm:
986// .lcomm Symbol, Length, Alignment, AccessAlignment
987bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
988 // FIXME: need better way to detect if AsmStreamer (upstream removed
989 // getKind())
990 if (getStreamer().hasRawTextSupport())
991 return true; // Only object file output requires special treatment.
992
993 StringRef Name;
994 if (getParser().parseIdentifier(Name))
995 return TokError("expected identifier in directive");
996 // Handle the identifier as the key symbol.
997 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
998
999 if (getLexer().isNot(AsmToken::Comma))
1000 return TokError("unexpected token in directive");
1001 Lex();
1002
1003 int64_t Size;
1004 SMLoc SizeLoc = getLexer().getLoc();
1005 if (getParser().parseAbsoluteExpression(Size))
1006 return true;
1007
1008 int64_t ByteAlignment = 1;
1009 SMLoc ByteAlignmentLoc;
1010 if (getLexer().is(AsmToken::Comma)) {
1011 Lex();
1012 ByteAlignmentLoc = getLexer().getLoc();
1013 if (getParser().parseAbsoluteExpression(ByteAlignment))
1014 return true;
1015 if (!isPowerOf2_64(ByteAlignment))
1016 return Error(ByteAlignmentLoc, "alignment must be a power of 2");
1017 }
1018
1019 int64_t AccessAlignment = 0;
1020 if (getLexer().is(AsmToken::Comma)) {
1021 // The optional access argument specifies the size of the smallest memory
1022 // access to be made to the symbol, expressed in bytes.
1023 SMLoc AccessAlignmentLoc;
1024 Lex();
1025 AccessAlignmentLoc = getLexer().getLoc();
1026 if (getParser().parseAbsoluteExpression(AccessAlignment))
1027 return true;
1028
1029 if (!isPowerOf2_64(AccessAlignment))
1030 return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
1031 }
1032
1033 if (getLexer().isNot(AsmToken::EndOfStatement))
1034 return TokError("unexpected token in '.comm' or '.lcomm' directive");
1035
1036 Lex();
1037
1038 // NOTE: a size of zero for a .comm should create a undefined symbol
1039 // but a size of .lcomm creates a bss symbol of size zero.
1040 if (Size < 0)
1041 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1042 "be less than zero");
1043
1044 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1045 // may internally end up wanting an alignment in bytes.
1046 // FIXME: Diagnose overflow.
1047 if (ByteAlignment < 0)
1048 return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1049 "alignment, can't be less than zero");
1050
1051 if (!Sym->isUndefined())
1052 return Error(Loc, "invalid symbol redefinition");
1053
1054 HexagonMCELFStreamer &HexagonELFStreamer =
1055 static_cast<HexagonMCELFStreamer &>(getStreamer());
1056 if (IsLocal) {
1057 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
1058 AccessAlignment);
1059 return false;
1060 }
1061
1062 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
1063 AccessAlignment);
1064 return false;
1065}
1066
1067// validate register against architecture
1068bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
1069 return true;
1070}
1071
1072// extern "C" void LLVMInitializeHexagonAsmLexer();
1073
1074/// Force static initialization.
1075extern "C" void LLVMInitializeHexagonAsmParser() {
Mehdi Aminif42454b2016-10-09 23:00:34 +00001076 RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001077}
1078
1079#define GET_MATCHER_IMPLEMENTATION
1080#define GET_REGISTER_MATCHER
1081#include "HexagonGenAsmMatcher.inc"
1082
Eugene Zelenko82085922016-12-13 22:13:50 +00001083static bool previousEqual(OperandVector &Operands, size_t Index,
1084 StringRef String) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001085 if (Index >= Operands.size())
1086 return false;
1087 MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
1088 if (!Operand.isToken())
1089 return false;
1090 return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
1091}
Eugene Zelenko82085922016-12-13 22:13:50 +00001092
1093static bool previousIsLoop(OperandVector &Operands, size_t Index) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001094 return previousEqual(Operands, Index, "loop0") ||
1095 previousEqual(Operands, Index, "loop1") ||
1096 previousEqual(Operands, Index, "sp1loop0") ||
1097 previousEqual(Operands, Index, "sp2loop0") ||
1098 previousEqual(Operands, Index, "sp3loop0");
1099}
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001100
1101bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
1102 AsmToken const &Token = getParser().getTok();
1103 StringRef String = Token.getString();
1104 SMLoc Loc = Token.getLoc();
Nirav Davefd910412016-06-17 16:06:17 +00001105 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001106 do {
1107 std::pair<StringRef, StringRef> HeadTail = String.split('.');
1108 if (!HeadTail.first.empty())
1109 Operands.push_back(HexagonOperand::CreateToken(HeadTail.first, Loc));
1110 if (!HeadTail.second.empty())
1111 Operands.push_back(HexagonOperand::CreateToken(
1112 String.substr(HeadTail.first.size(), 1), Loc));
1113 String = HeadTail.second;
1114 } while (!String.empty());
1115 return false;
1116}
1117
1118bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
1119 unsigned Register;
1120 SMLoc Begin;
1121 SMLoc End;
1122 MCAsmLexer &Lexer = getLexer();
1123 if (!ParseRegister(Register, Begin, End)) {
1124 if (!ErrorMissingParenthesis)
1125 switch (Register) {
1126 default:
1127 break;
1128 case Hexagon::P0:
1129 case Hexagon::P1:
1130 case Hexagon::P2:
1131 case Hexagon::P3:
1132 if (previousEqual(Operands, 0, "if")) {
1133 if (WarnMissingParenthesis)
1134 Warning (Begin, "Missing parenthesis around predicate register");
1135 static char const *LParen = "(";
1136 static char const *RParen = ")";
1137 Operands.push_back(HexagonOperand::CreateToken(LParen, Begin));
1138 Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
Benjamin Kramer4ca41fd2016-06-12 17:30:47 +00001139 const AsmToken &MaybeDotNew = Lexer.getTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001140 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
1141 MaybeDotNew.getString().equals_lower(".new"))
1142 splitIdentifier(Operands);
1143 Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
1144 return false;
1145 }
1146 if (previousEqual(Operands, 0, "!") &&
1147 previousEqual(Operands, 1, "if")) {
1148 if (WarnMissingParenthesis)
1149 Warning (Begin, "Missing parenthesis around predicate register");
1150 static char const *LParen = "(";
1151 static char const *RParen = ")";
1152 Operands.insert(Operands.end () - 1,
1153 HexagonOperand::CreateToken(LParen, Begin));
1154 Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
Benjamin Kramer4ca41fd2016-06-12 17:30:47 +00001155 const AsmToken &MaybeDotNew = Lexer.getTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001156 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
1157 MaybeDotNew.getString().equals_lower(".new"))
1158 splitIdentifier(Operands);
1159 Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
1160 return false;
1161 }
1162 break;
1163 }
1164 Operands.push_back(HexagonOperand::CreateReg(
1165 Register, Begin, End));
1166 return false;
1167 }
1168 return splitIdentifier(Operands);
1169}
1170
1171bool HexagonAsmParser::isLabel(AsmToken &Token) {
1172 MCAsmLexer &Lexer = getLexer();
1173 AsmToken const &Second = Lexer.getTok();
1174 AsmToken Third = Lexer.peekTok();
1175 StringRef String = Token.getString();
1176 if (Token.is(AsmToken::TokenKind::LCurly) ||
1177 Token.is(AsmToken::TokenKind::RCurly))
1178 return false;
1179 if (!Token.is(AsmToken::TokenKind::Identifier))
1180 return true;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001181 if (!matchRegister(String.lower()))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001182 return true;
Colin LeMahieu9d851f02015-11-09 21:06:28 +00001183 (void)Second;
1184 assert(Second.is(AsmToken::Colon));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001185 StringRef Raw (String.data(), Third.getString().data() - String.data() +
1186 Third.getString().size());
1187 std::string Collapsed = Raw;
Eugene Zelenko82085922016-12-13 22:13:50 +00001188 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001189 StringRef Whole = Collapsed;
1190 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001191 if (!matchRegister(DotSplit.first.lower()))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001192 return true;
1193 return false;
1194}
1195
1196bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious, SMLoc &Loc) {
1197 if (!Contigious && ErrorNoncontigiousRegister) {
1198 Error(Loc, "Register name is not contigious");
1199 return true;
1200 }
1201 if (!Contigious && WarnNoncontigiousRegister)
1202 Warning(Loc, "Register name is not contigious");
1203 return false;
1204}
1205
1206bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
1207 MCAsmLexer &Lexer = getLexer();
1208 StartLoc = getLexer().getLoc();
1209 SmallVector<AsmToken, 5> Lookahead;
1210 StringRef RawString(Lexer.getTok().getString().data(), 0);
1211 bool Again = Lexer.is(AsmToken::Identifier);
1212 bool NeededWorkaround = false;
1213 while (Again) {
1214 AsmToken const &Token = Lexer.getTok();
1215 RawString = StringRef(RawString.data(),
1216 Token.getString().data() - RawString.data () +
1217 Token.getString().size());
1218 Lookahead.push_back(Token);
1219 Lexer.Lex();
1220 bool Contigious = Lexer.getTok().getString().data() ==
1221 Lookahead.back().getString().data() +
1222 Lookahead.back().getString().size();
1223 bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1224 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1225 Lexer.is(AsmToken::Colon);
1226 bool Workaround = Lexer.is(AsmToken::Colon) ||
1227 Lookahead.back().is(AsmToken::Colon);
1228 Again = (Contigious && Type) || (Workaround && Type);
1229 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1230 }
1231 std::string Collapsed = RawString;
Eugene Zelenko82085922016-12-13 22:13:50 +00001232 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001233 StringRef FullString = Collapsed;
1234 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001235 unsigned DotReg = matchRegister(DotSplit.first.lower());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001236 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1237 if (DotSplit.second.empty()) {
1238 RegNo = DotReg;
1239 EndLoc = Lexer.getLoc();
1240 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1241 return true;
1242 return false;
1243 } else {
1244 RegNo = DotReg;
1245 size_t First = RawString.find('.');
1246 StringRef DotString (RawString.data() + First, RawString.size() - First);
1247 Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1248 EndLoc = Lexer.getLoc();
1249 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1250 return true;
1251 return false;
1252 }
1253 }
1254 std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001255 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001256 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1257 Lexer.UnLex(Lookahead.back());
1258 Lookahead.pop_back();
1259 Lexer.UnLex(Lookahead.back());
1260 Lookahead.pop_back();
1261 RegNo = ColonReg;
1262 EndLoc = Lexer.getLoc();
1263 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1264 return true;
1265 return false;
1266 }
1267 while (!Lookahead.empty()) {
1268 Lexer.UnLex(Lookahead.back());
1269 Lookahead.pop_back();
1270 }
1271 return true;
1272}
1273
1274bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1275 if (previousEqual(Operands, 0, "call"))
1276 return true;
1277 if (previousEqual(Operands, 0, "jump"))
1278 if (!getLexer().getTok().is(AsmToken::Colon))
1279 return true;
1280 if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1281 return true;
1282 if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1283 (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1284 return true;
1285 return false;
1286}
1287
1288bool HexagonAsmParser::parseExpression(MCExpr const *& Expr) {
Eugene Zelenko82085922016-12-13 22:13:50 +00001289 SmallVector<AsmToken, 4> Tokens;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001290 MCAsmLexer &Lexer = getLexer();
1291 bool Done = false;
1292 static char const * Comma = ",";
1293 do {
1294 Tokens.emplace_back (Lexer.getTok());
Nirav Davefd910412016-06-17 16:06:17 +00001295 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001296 switch (Tokens.back().getKind())
1297 {
1298 case AsmToken::TokenKind::Hash:
1299 if (Tokens.size () > 1)
1300 if ((Tokens.end () - 2)->getKind() == AsmToken::TokenKind::Plus) {
1301 Tokens.insert(Tokens.end() - 2,
1302 AsmToken(AsmToken::TokenKind::Comma, Comma));
1303 Done = true;
1304 }
1305 break;
1306 case AsmToken::TokenKind::RCurly:
1307 case AsmToken::TokenKind::EndOfStatement:
1308 case AsmToken::TokenKind::Eof:
1309 Done = true;
1310 break;
1311 default:
1312 break;
1313 }
1314 } while (!Done);
1315 while (!Tokens.empty()) {
1316 Lexer.UnLex(Tokens.back());
1317 Tokens.pop_back();
1318 }
1319 return getParser().parseExpression(Expr);
1320}
1321
1322bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1323 if (implicitExpressionLocation(Operands)) {
1324 MCAsmParser &Parser = getParser();
1325 SMLoc Loc = Parser.getLexer().getLoc();
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001326 MCExpr const *Expr = nullptr;
1327 bool Error = parseExpression(Expr);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001328 Expr = HexagonMCExpr::create(Expr, getContext());
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001329 if (!Error)
1330 Operands.push_back(HexagonOperand::CreateImm(Expr, Loc, Loc));
1331 return Error;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001332 }
1333 return parseOperand(Operands);
1334}
1335
1336/// Parse an instruction.
1337bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1338 MCAsmParser &Parser = getParser();
1339 MCAsmLexer &Lexer = getLexer();
1340 while (true) {
1341 AsmToken const &Token = Parser.getTok();
1342 switch (Token.getKind()) {
1343 case AsmToken::EndOfStatement: {
Nirav Davefd910412016-06-17 16:06:17 +00001344 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001345 return false;
1346 }
1347 case AsmToken::LCurly: {
1348 if (!Operands.empty())
1349 return true;
1350 Operands.push_back(
1351 HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001352 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001353 return false;
1354 }
1355 case AsmToken::RCurly: {
1356 if (Operands.empty()) {
1357 Operands.push_back(
1358 HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001359 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001360 }
1361 return false;
1362 }
1363 case AsmToken::Comma: {
Nirav Davefd910412016-06-17 16:06:17 +00001364 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001365 continue;
1366 }
1367 case AsmToken::EqualEqual:
1368 case AsmToken::ExclaimEqual:
1369 case AsmToken::GreaterEqual:
1370 case AsmToken::GreaterGreater:
1371 case AsmToken::LessEqual:
1372 case AsmToken::LessLess: {
1373 Operands.push_back(HexagonOperand::CreateToken(
1374 Token.getString().substr(0, 1), Token.getLoc()));
1375 Operands.push_back(HexagonOperand::CreateToken(
1376 Token.getString().substr(1, 1), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001377 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001378 continue;
1379 }
1380 case AsmToken::Hash: {
1381 bool MustNotExtend = false;
1382 bool ImplicitExpression = implicitExpressionLocation(Operands);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001383 SMLoc ExprLoc = Lexer.getLoc();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001384 if (!ImplicitExpression)
1385 Operands.push_back(
1386 HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001387 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001388 bool MustExtend = false;
1389 bool HiOnly = false;
1390 bool LoOnly = false;
1391 if (Lexer.is(AsmToken::Hash)) {
Nirav Davefd910412016-06-17 16:06:17 +00001392 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001393 MustExtend = true;
1394 } else if (ImplicitExpression)
1395 MustNotExtend = true;
1396 AsmToken const &Token = Parser.getTok();
1397 if (Token.is(AsmToken::Identifier)) {
1398 StringRef String = Token.getString();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001399 if (String.lower() == "hi") {
1400 HiOnly = true;
1401 } else if (String.lower() == "lo") {
1402 LoOnly = true;
1403 }
1404 if (HiOnly || LoOnly) {
1405 AsmToken LParen = Lexer.peekTok();
1406 if (!LParen.is(AsmToken::LParen)) {
1407 HiOnly = false;
1408 LoOnly = false;
1409 } else {
Nirav Davefd910412016-06-17 16:06:17 +00001410 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001411 }
1412 }
1413 }
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001414 MCExpr const *Expr = nullptr;
1415 if (parseExpression(Expr))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001416 return true;
1417 int64_t Value;
1418 MCContext &Context = Parser.getContext();
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001419 assert(Expr != nullptr);
1420 if (Expr->evaluateAsAbsolute(Value)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001421 if (HiOnly)
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001422 Expr = MCBinaryExpr::createLShr(
1423 Expr, MCConstantExpr::create(16, Context), Context);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001424 if (HiOnly || LoOnly)
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001425 Expr = MCBinaryExpr::createAnd(Expr,
1426 MCConstantExpr::create(0xffff, Context),
1427 Context);
Colin LeMahieu5cb6eea2016-03-01 21:37:41 +00001428 } else {
1429 MCValue Value;
1430 if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1431 if (!Value.isAbsolute()) {
1432 switch(Value.getAccessVariant()) {
1433 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1434 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1435 // Don't lazy extend these expression variants
1436 MustNotExtend = !MustExtend;
1437 break;
1438 default:
1439 break;
1440 }
1441 }
1442 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001443 }
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001444 Expr = HexagonMCExpr::create(Expr, Context);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001445 HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001446 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001447 std::unique_ptr<HexagonOperand> Operand =
1448 HexagonOperand::CreateImm(Expr, ExprLoc, ExprLoc);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001449 Operands.push_back(std::move(Operand));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001450 continue;
1451 }
1452 default:
1453 break;
1454 }
1455 if (parseExpressionOrOperand(Operands))
1456 return true;
1457 }
1458}
1459
1460bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1461 StringRef Name,
1462 AsmToken ID,
1463 OperandVector &Operands) {
1464 getLexer().UnLex(ID);
1465 return parseInstruction(Operands);
1466}
1467
Eugene Zelenko82085922016-12-13 22:13:50 +00001468static MCInst makeCombineInst(int opCode, MCOperand &Rdd,
1469 MCOperand &MO1, MCOperand &MO2) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001470 MCInst TmpInst;
1471 TmpInst.setOpcode(opCode);
1472 TmpInst.addOperand(Rdd);
1473 TmpInst.addOperand(MO1);
1474 TmpInst.addOperand(MO2);
1475
1476 return TmpInst;
1477}
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001478
1479// Define this matcher function after the auto-generated include so we
1480// have the match class enum definitions.
1481unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1482 unsigned Kind) {
1483 HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1484
1485 switch (Kind) {
1486 case MCK_0: {
1487 int64_t Value;
1488 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1489 ? Match_Success
1490 : Match_InvalidOperand;
1491 }
1492 case MCK_1: {
1493 int64_t Value;
1494 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1495 ? Match_Success
1496 : Match_InvalidOperand;
1497 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001498 }
1499 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1500 StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1501 if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1502 return Match_Success;
1503 if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1504 return Match_Success;
1505 }
1506
1507 DEBUG(dbgs() << "Unmatched Operand:");
1508 DEBUG(Op->dump());
1509 DEBUG(dbgs() << "\n");
1510
1511 return Match_InvalidOperand;
1512}
1513
Nirav Dave2364748a2016-09-16 18:30:20 +00001514// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1515bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001516 std::string errStr;
1517 raw_string_ostream ES(errStr);
Alexey Samsonov44ff2042015-12-02 22:59:22 +00001518 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001519 if (Max >= 0)
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001520 ES << "0-" << Max;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001521 else
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001522 ES << Max << "-" << (-Max - 1);
Malcolm Parsons06ac79c2016-11-02 16:43:50 +00001523 return Parser.printError(IDLoc, ES.str());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001524}
1525
1526int HexagonAsmParser::processInstruction(MCInst &Inst,
1527 OperandVector const &Operands,
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001528 SMLoc IDLoc) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001529 MCContext &Context = getParser().getContext();
1530 const MCRegisterInfo *RI = getContext().getRegisterInfo();
1531 std::string r = "r";
1532 std::string v = "v";
1533 std::string Colon = ":";
1534
1535 bool is32bit = false; // used to distinguish between CONST32 and CONST64
1536 switch (Inst.getOpcode()) {
1537 default:
1538 break;
1539
Colin LeMahieuecef1d92016-02-16 20:38:17 +00001540 case Hexagon::A2_iconst: {
1541 Inst.setOpcode(Hexagon::A2_addi);
1542 MCOperand Reg = Inst.getOperand(0);
1543 MCOperand S16 = Inst.getOperand(1);
1544 HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
1545 HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
1546 Inst.clear();
1547 Inst.addOperand(Reg);
1548 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1549 Inst.addOperand(S16);
1550 break;
1551 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001552 case Hexagon::M4_mpyrr_addr:
1553 case Hexagon::S4_addi_asl_ri:
1554 case Hexagon::S4_addi_lsr_ri:
1555 case Hexagon::S4_andi_asl_ri:
1556 case Hexagon::S4_andi_lsr_ri:
1557 case Hexagon::S4_ori_asl_ri:
1558 case Hexagon::S4_ori_lsr_ri:
1559 case Hexagon::S4_or_andix:
1560 case Hexagon::S4_subi_asl_ri:
1561 case Hexagon::S4_subi_lsr_ri: {
1562 MCOperand &Ry = Inst.getOperand(0);
1563 MCOperand &src = Inst.getOperand(2);
1564 if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1565 return Match_InvalidOperand;
1566 break;
1567 }
1568
1569 case Hexagon::C2_cmpgei: {
1570 MCOperand &MO = Inst.getOperand(2);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001571 MO.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001572 MO.getExpr(), MCConstantExpr::create(1, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001573 Inst.setOpcode(Hexagon::C2_cmpgti);
1574 break;
1575 }
1576
1577 case Hexagon::C2_cmpgeui: {
1578 MCOperand &MO = Inst.getOperand(2);
1579 int64_t Value;
1580 bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
Colin LeMahieu9d851f02015-11-09 21:06:28 +00001581 (void)Success;
1582 assert(Success && "Assured by matcher");
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001583 if (Value == 0) {
1584 MCInst TmpInst;
1585 MCOperand &Pd = Inst.getOperand(0);
1586 MCOperand &Rt = Inst.getOperand(1);
1587 TmpInst.setOpcode(Hexagon::C2_cmpeq);
1588 TmpInst.addOperand(Pd);
1589 TmpInst.addOperand(Rt);
1590 TmpInst.addOperand(Rt);
1591 Inst = TmpInst;
1592 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001593 MO.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001594 MO.getExpr(), MCConstantExpr::create(1, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001595 Inst.setOpcode(Hexagon::C2_cmpgtui);
1596 }
1597 break;
1598 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001599
1600 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1601 case Hexagon::A2_tfrp: {
1602 MCOperand &MO = Inst.getOperand(1);
1603 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001604 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001605 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001606 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001607 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001608 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001609 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001610 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001611 Inst.setOpcode(Hexagon::A2_combinew);
1612 break;
1613 }
1614
1615 case Hexagon::A2_tfrpt:
1616 case Hexagon::A2_tfrpf: {
1617 MCOperand &MO = Inst.getOperand(2);
1618 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001619 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001620 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001621 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001622 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001623 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001624 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001625 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001626 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1627 ? Hexagon::C2_ccombinewt
1628 : Hexagon::C2_ccombinewf);
1629 break;
1630 }
1631 case Hexagon::A2_tfrptnew:
1632 case Hexagon::A2_tfrpfnew: {
1633 MCOperand &MO = Inst.getOperand(2);
1634 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001635 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001636 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001637 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001638 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001639 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001640 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001641 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001642 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1643 ? Hexagon::C2_ccombinewnewt
1644 : Hexagon::C2_ccombinewnewf);
1645 break;
1646 }
1647
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001648 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001649 case Hexagon::V6_vassignp: {
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001650 MCOperand &MO = Inst.getOperand(1);
1651 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001652 std::string R1 = v + utostr(RegPairNum + 1);
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001653 MO.setReg(MatchRegisterName(R1));
1654 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001655 std::string R2 = v + utostr(RegPairNum);
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001656 Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
1657 Inst.setOpcode(Hexagon::V6_vcombine);
1658 break;
1659 }
1660
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001661 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1662 case Hexagon::CONST32:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001663 is32bit = true;
1664 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
Krzysztof Parzyszeka3386502016-08-10 16:46:36 +00001665 case Hexagon::CONST64:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001666 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1667 if (!Parser.getStreamer().hasRawTextSupport()) {
1668 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1669 MCOperand &MO_1 = Inst.getOperand(1);
1670 MCOperand &MO_0 = Inst.getOperand(0);
1671
1672 // push section onto section stack
1673 MES->PushSection();
1674
1675 std::string myCharStr;
1676 MCSectionELF *mySection;
1677
1678 // check if this as an immediate or a symbol
1679 int64_t Value;
1680 bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1681 if (Absolute) {
1682 // Create a new section - one for each constant
1683 // Some or all of the zeros are replaced with the given immediate.
1684 if (is32bit) {
1685 std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1686 myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1687 .drop_back(myImmStr.size())
1688 .str() +
1689 myImmStr;
1690 } else {
1691 std::string myImmStr = utohexstr(Value);
1692 myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1693 .drop_back(myImmStr.size())
1694 .str() +
1695 myImmStr;
1696 }
1697
1698 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1699 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1700 } else if (MO_1.isExpr()) {
1701 // .lita - for expressions
1702 myCharStr = ".lita";
1703 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1704 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1705 } else
1706 llvm_unreachable("unexpected type of machine operand!");
1707
1708 MES->SwitchSection(mySection);
1709 unsigned byteSize = is32bit ? 4 : 8;
1710 getStreamer().EmitCodeAlignment(byteSize, byteSize);
1711
1712 MCSymbol *Sym;
1713
1714 // for symbols, get rid of prepended ".gnu.linkonce.lx."
1715
1716 // emit symbol if needed
1717 if (Absolute) {
1718 Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1719 if (Sym->isUndefined()) {
1720 getStreamer().EmitLabel(Sym);
1721 getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1722 getStreamer().EmitIntValue(Value, byteSize);
1723 }
1724 } else if (MO_1.isExpr()) {
Eugene Zelenko82085922016-12-13 22:13:50 +00001725 const char *StringStart = nullptr;
1726 const char *StringEnd = nullptr;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001727 if (*Operands[4]->getStartLoc().getPointer() == '#') {
1728 StringStart = Operands[5]->getStartLoc().getPointer();
1729 StringEnd = Operands[6]->getStartLoc().getPointer();
1730 } else { // no pound
1731 StringStart = Operands[4]->getStartLoc().getPointer();
1732 StringEnd = Operands[5]->getStartLoc().getPointer();
1733 }
1734
1735 unsigned size = StringEnd - StringStart;
1736 std::string DotConst = ".CONST_";
1737 Sym = getContext().getOrCreateSymbol(DotConst +
1738 StringRef(StringStart, size));
1739
1740 if (Sym->isUndefined()) {
1741 // case where symbol is not yet defined: emit symbol
1742 getStreamer().EmitLabel(Sym);
1743 getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1744 getStreamer().EmitValue(MO_1.getExpr(), 4);
1745 }
1746 } else
1747 llvm_unreachable("unexpected type of machine operand!");
1748
1749 MES->PopSection();
1750
1751 if (Sym) {
1752 MCInst TmpInst;
1753 if (is32bit) // 32 bit
1754 TmpInst.setOpcode(Hexagon::L2_loadrigp);
1755 else // 64 bit
1756 TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1757
1758 TmpInst.addOperand(MO_0);
Krzysztof Parzyszekd0d42f02017-02-02 20:35:12 +00001759 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
1760 MCSymbolRefExpr::create(Sym, getContext()), getContext())));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001761 Inst = TmpInst;
1762 }
1763 }
1764 break;
1765
1766 // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1767 case Hexagon::A2_tfrpi: {
1768 MCOperand &Rdd = Inst.getOperand(0);
1769 MCOperand &MO = Inst.getOperand(1);
1770 int64_t Value;
1771 int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001772 MCOperand imm(MCOperand::createExpr(
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001773 HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001774 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1775 break;
1776 }
1777
1778 // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1779 case Hexagon::TFRI64_V4: {
1780 MCOperand &Rdd = Inst.getOperand(0);
1781 MCOperand &MO = Inst.getOperand(1);
1782 int64_t Value;
1783 if (MO.getExpr()->evaluateAsAbsolute(Value)) {
David Majnemere61e4bf2016-06-21 05:10:24 +00001784 int s8 = Hi_32(Value);
1785 if (!isInt<8>(s8))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001786 OutOfRange(IDLoc, s8, -128);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001787 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001788 MCConstantExpr::create(s8, Context), Context))); // upper 32
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001789 auto Expr = HexagonMCExpr::create(
David Majnemere61e4bf2016-06-21 05:10:24 +00001790 MCConstantExpr::create(Lo_32(Value), Context), Context);
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001791 HexagonMCInstrInfo::setMustExtend(*Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
1792 MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001793 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1794 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001795 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001796 MCConstantExpr::create(0, Context), Context))); // upper 32
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001797 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1798 }
1799 break;
1800 }
1801
1802 // Handle $Rdd = combine(##imm, #imm)"
1803 case Hexagon::TFRI64_V2_ext: {
1804 MCOperand &Rdd = Inst.getOperand(0);
1805 MCOperand &MO1 = Inst.getOperand(1);
1806 MCOperand &MO2 = Inst.getOperand(2);
1807 int64_t Value;
1808 if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1809 int s8 = Value;
1810 if (s8 < -128 || s8 > 127)
1811 OutOfRange(IDLoc, s8, -128);
1812 }
1813 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1814 break;
1815 }
1816
1817 // Handle $Rdd = combine(#imm, ##imm)"
1818 case Hexagon::A4_combineii: {
1819 MCOperand &Rdd = Inst.getOperand(0);
1820 MCOperand &MO1 = Inst.getOperand(1);
1821 int64_t Value;
1822 if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1823 int s8 = Value;
1824 if (s8 < -128 || s8 > 127)
1825 OutOfRange(IDLoc, s8, -128);
1826 }
1827 MCOperand &MO2 = Inst.getOperand(2);
1828 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1829 break;
1830 }
1831
Eugene Zelenko82085922016-12-13 22:13:50 +00001832 case Hexagon::S2_tableidxb_goodsyntax:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001833 Inst.setOpcode(Hexagon::S2_tableidxb);
1834 break;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001835
1836 case Hexagon::S2_tableidxh_goodsyntax: {
1837 MCInst TmpInst;
1838 MCOperand &Rx = Inst.getOperand(0);
1839 MCOperand &_dst_ = Inst.getOperand(1);
1840 MCOperand &Rs = Inst.getOperand(2);
1841 MCOperand &Imm4 = Inst.getOperand(3);
1842 MCOperand &Imm6 = Inst.getOperand(4);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001843 Imm6.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001844 Imm6.getExpr(), MCConstantExpr::create(1, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001845 TmpInst.setOpcode(Hexagon::S2_tableidxh);
1846 TmpInst.addOperand(Rx);
1847 TmpInst.addOperand(_dst_);
1848 TmpInst.addOperand(Rs);
1849 TmpInst.addOperand(Imm4);
1850 TmpInst.addOperand(Imm6);
1851 Inst = TmpInst;
1852 break;
1853 }
1854
1855 case Hexagon::S2_tableidxw_goodsyntax: {
1856 MCInst TmpInst;
1857 MCOperand &Rx = Inst.getOperand(0);
1858 MCOperand &_dst_ = Inst.getOperand(1);
1859 MCOperand &Rs = Inst.getOperand(2);
1860 MCOperand &Imm4 = Inst.getOperand(3);
1861 MCOperand &Imm6 = Inst.getOperand(4);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001862 Imm6.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001863 Imm6.getExpr(), MCConstantExpr::create(2, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001864 TmpInst.setOpcode(Hexagon::S2_tableidxw);
1865 TmpInst.addOperand(Rx);
1866 TmpInst.addOperand(_dst_);
1867 TmpInst.addOperand(Rs);
1868 TmpInst.addOperand(Imm4);
1869 TmpInst.addOperand(Imm6);
1870 Inst = TmpInst;
1871 break;
1872 }
1873
1874 case Hexagon::S2_tableidxd_goodsyntax: {
1875 MCInst TmpInst;
1876 MCOperand &Rx = Inst.getOperand(0);
1877 MCOperand &_dst_ = Inst.getOperand(1);
1878 MCOperand &Rs = Inst.getOperand(2);
1879 MCOperand &Imm4 = Inst.getOperand(3);
1880 MCOperand &Imm6 = Inst.getOperand(4);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001881 Imm6.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001882 Imm6.getExpr(), MCConstantExpr::create(3, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001883 TmpInst.setOpcode(Hexagon::S2_tableidxd);
1884 TmpInst.addOperand(Rx);
1885 TmpInst.addOperand(_dst_);
1886 TmpInst.addOperand(Rs);
1887 TmpInst.addOperand(Imm4);
1888 TmpInst.addOperand(Imm6);
1889 Inst = TmpInst;
1890 break;
1891 }
1892
Eugene Zelenko82085922016-12-13 22:13:50 +00001893 case Hexagon::M2_mpyui:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001894 Inst.setOpcode(Hexagon::M2_mpyi);
1895 break;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001896 case Hexagon::M2_mpysmi: {
1897 MCInst TmpInst;
1898 MCOperand &Rd = Inst.getOperand(0);
1899 MCOperand &Rs = Inst.getOperand(1);
1900 MCOperand &Imm = Inst.getOperand(2);
1901 int64_t Value;
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001902 MCExpr const &Expr = *Imm.getExpr();
1903 bool Absolute = Expr.evaluateAsAbsolute(Value);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001904 assert(Absolute);
1905 (void)Absolute;
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001906 if (!HexagonMCInstrInfo::mustExtend(Expr)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001907 if (Value < 0 && Value > -256) {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001908 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001909 MCConstantExpr::create(Value * -1, Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001910 TmpInst.setOpcode(Hexagon::M2_mpysin);
1911 } else if (Value < 256 && Value >= 0)
1912 TmpInst.setOpcode(Hexagon::M2_mpysip);
1913 else
1914 return Match_InvalidOperand;
1915 } else {
1916 if (Value >= 0)
1917 TmpInst.setOpcode(Hexagon::M2_mpysip);
1918 else
1919 return Match_InvalidOperand;
1920 }
1921 TmpInst.addOperand(Rd);
1922 TmpInst.addOperand(Rs);
1923 TmpInst.addOperand(Imm);
1924 Inst = TmpInst;
1925 break;
1926 }
1927
1928 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1929 MCOperand &Imm = Inst.getOperand(2);
1930 MCInst TmpInst;
1931 int64_t Value;
1932 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1933 assert(Absolute);
1934 (void)Absolute;
1935 if (Value == 0) { // convert to $Rd = $Rs
1936 TmpInst.setOpcode(Hexagon::A2_tfr);
1937 MCOperand &Rd = Inst.getOperand(0);
1938 MCOperand &Rs = Inst.getOperand(1);
1939 TmpInst.addOperand(Rd);
1940 TmpInst.addOperand(Rs);
1941 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001942 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001943 MCBinaryExpr::createSub(Imm.getExpr(),
1944 MCConstantExpr::create(1, Context), Context),
1945 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001946 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1947 MCOperand &Rd = Inst.getOperand(0);
1948 MCOperand &Rs = Inst.getOperand(1);
1949 TmpInst.addOperand(Rd);
1950 TmpInst.addOperand(Rs);
1951 TmpInst.addOperand(Imm);
1952 }
1953 Inst = TmpInst;
1954 break;
1955 }
1956
1957 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1958 MCOperand &Rdd = Inst.getOperand(0);
1959 MCOperand &Rss = Inst.getOperand(1);
1960 MCOperand &Imm = Inst.getOperand(2);
1961 int64_t Value;
1962 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1963 assert(Absolute);
1964 (void)Absolute;
1965 if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1966 MCInst TmpInst;
1967 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001968 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001969 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001970 Rss.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001971 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001972 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001973 StringRef Reg2(R2);
1974 TmpInst.setOpcode(Hexagon::A2_combinew);
1975 TmpInst.addOperand(Rdd);
1976 TmpInst.addOperand(Rss);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001977 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001978 Inst = TmpInst;
1979 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001980 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001981 MCBinaryExpr::createSub(Imm.getExpr(),
1982 MCConstantExpr::create(1, Context), Context),
1983 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001984 Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1985 }
1986 break;
1987 }
1988
1989 case Hexagon::A4_boundscheck: {
1990 MCOperand &Rs = Inst.getOperand(1);
1991 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1992 if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1993 Inst.setOpcode(Hexagon::A4_boundscheck_hi);
Eugene Zelenko82085922016-12-13 22:13:50 +00001994 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001995 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001996 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001997 } else { // raw:lo
1998 Inst.setOpcode(Hexagon::A4_boundscheck_lo);
Eugene Zelenko82085922016-12-13 22:13:50 +00001999 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002000 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002001 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002002 }
2003 break;
2004 }
2005
2006 case Hexagon::A2_addsp: {
2007 MCOperand &Rs = Inst.getOperand(1);
2008 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
2009 if (RegNum & 1) { // Odd mapped to raw:hi
2010 Inst.setOpcode(Hexagon::A2_addsph);
Eugene Zelenko82085922016-12-13 22:13:50 +00002011 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002012 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002013 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002014 } else { // Even mapped raw:lo
2015 Inst.setOpcode(Hexagon::A2_addspl);
Eugene Zelenko82085922016-12-13 22:13:50 +00002016 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002017 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002018 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002019 }
2020 break;
2021 }
2022
2023 case Hexagon::M2_vrcmpys_s1: {
2024 MCOperand &Rt = Inst.getOperand(2);
2025 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
2026 if (RegNum & 1) { // Odd mapped to sat:raw:hi
2027 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00002028 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002029 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002030 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002031 } else { // Even mapped sat:raw:lo
2032 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00002033 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002034 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002035 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002036 }
2037 break;
2038 }
2039
2040 case Hexagon::M2_vrcmpys_acc_s1: {
2041 MCInst TmpInst;
2042 MCOperand &Rxx = Inst.getOperand(0);
2043 MCOperand &Rss = Inst.getOperand(2);
2044 MCOperand &Rt = Inst.getOperand(3);
2045 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
2046 if (RegNum & 1) { // Odd mapped to sat:raw:hi
2047 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00002048 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002049 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002050 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002051 } else { // Even mapped sat:raw:lo
2052 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00002053 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002054 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002055 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002056 }
2057 // Registers are in different positions
2058 TmpInst.addOperand(Rxx);
2059 TmpInst.addOperand(Rxx);
2060 TmpInst.addOperand(Rss);
2061 TmpInst.addOperand(Rt);
2062 Inst = TmpInst;
2063 break;
2064 }
2065
2066 case Hexagon::M2_vrcmpys_s1rp: {
2067 MCOperand &Rt = Inst.getOperand(2);
2068 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
2069 if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
2070 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00002071 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002072 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002073 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002074 } else { // Even mapped rnd:sat:raw:lo
2075 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00002076 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002077 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002078 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002079 }
2080 break;
2081 }
2082
2083 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
2084 MCOperand &Imm = Inst.getOperand(2);
2085 int64_t Value;
2086 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
2087 assert(Absolute);
2088 (void)Absolute;
2089 if (Value == 0)
2090 Inst.setOpcode(Hexagon::S2_vsathub);
2091 else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00002092 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00002093 MCBinaryExpr::createSub(Imm.getExpr(),
2094 MCConstantExpr::create(1, Context), Context),
2095 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002096 Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
2097 }
2098 break;
2099 }
2100
2101 case Hexagon::S5_vasrhrnd_goodsyntax: {
2102 MCOperand &Rdd = Inst.getOperand(0);
2103 MCOperand &Rss = Inst.getOperand(1);
2104 MCOperand &Imm = Inst.getOperand(2);
2105 int64_t Value;
2106 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
2107 assert(Absolute);
2108 (void)Absolute;
2109 if (Value == 0) {
2110 MCInst TmpInst;
2111 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00002112 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002113 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002114 Rss.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002115 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00002116 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002117 StringRef Reg2(R2);
2118 TmpInst.setOpcode(Hexagon::A2_combinew);
2119 TmpInst.addOperand(Rdd);
2120 TmpInst.addOperand(Rss);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002121 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002122 Inst = TmpInst;
2123 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00002124 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00002125 MCBinaryExpr::createSub(Imm.getExpr(),
2126 MCConstantExpr::create(1, Context), Context),
2127 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002128 Inst.setOpcode(Hexagon::S5_vasrhrnd);
2129 }
2130 break;
2131 }
2132
2133 case Hexagon::A2_not: {
2134 MCInst TmpInst;
2135 MCOperand &Rd = Inst.getOperand(0);
2136 MCOperand &Rs = Inst.getOperand(1);
2137 TmpInst.setOpcode(Hexagon::A2_subri);
2138 TmpInst.addOperand(Rd);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00002139 TmpInst.addOperand(MCOperand::createExpr(
Colin LeMahieuc7b21242016-02-15 18:47:55 +00002140 HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002141 TmpInst.addOperand(Rs);
2142 Inst = TmpInst;
2143 break;
2144 }
Krzysztof Parzyszek5b4a6b62017-02-06 23:18:57 +00002145 case Hexagon::PS_loadrubabs:
2146 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2147 Inst.setOpcode(Hexagon::L2_loadrubgp);
2148 break;
2149 case Hexagon::PS_loadrbabs:
2150 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2151 Inst.setOpcode(Hexagon::L2_loadrbgp);
2152 break;
2153 case Hexagon::PS_loadruhabs:
2154 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2155 Inst.setOpcode(Hexagon::L2_loadruhgp);
2156 break;
2157 case Hexagon::PS_loadrhabs:
2158 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2159 Inst.setOpcode(Hexagon::L2_loadrhgp);
2160 break;
2161 case Hexagon::PS_loadriabs:
2162 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2163 Inst.setOpcode(Hexagon::L2_loadrigp);
2164 break;
2165 case Hexagon::PS_loadrdabs:
2166 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2167 Inst.setOpcode(Hexagon::L2_loadrdgp);
2168 break;
2169 case Hexagon::PS_storerbabs:
2170 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2171 Inst.setOpcode(Hexagon::S2_storerbgp);
2172 break;
2173 case Hexagon::PS_storerhabs:
2174 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2175 Inst.setOpcode(Hexagon::S2_storerhgp);
2176 break;
2177 case Hexagon::PS_storerfabs:
2178 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2179 Inst.setOpcode(Hexagon::S2_storerfgp);
2180 break;
2181 case Hexagon::PS_storeriabs:
2182 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2183 Inst.setOpcode(Hexagon::S2_storerigp);
2184 break;
2185 case Hexagon::PS_storerdabs:
2186 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2187 Inst.setOpcode(Hexagon::S2_storerdgp);
2188 break;
2189 case Hexagon::PS_storerbnewabs:
2190 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2191 Inst.setOpcode(Hexagon::S2_storerbnewgp);
2192 break;
2193 case Hexagon::PS_storerhnewabs:
2194 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2195 Inst.setOpcode(Hexagon::S2_storerhnewgp);
2196 break;
2197 case Hexagon::PS_storerinewabs:
2198 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2199 Inst.setOpcode(Hexagon::S2_storerinewgp);
2200 break;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002201 } // switch
2202
2203 return Match_Success;
2204}
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002205
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002206unsigned HexagonAsmParser::matchRegister(StringRef Name) {
2207 if (unsigned Reg = MatchRegisterName(Name))
2208 return Reg;
2209 return MatchRegisterAltName(Name);
2210}