blob: 1aab5a00021a58355708ea71c9d64c97d886f70a [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
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +000066static cl::opt<bool> WarnMissingParenthesis(
67 "mwarn-missing-parenthesis",
68 cl::desc("Warn for missing parenthesis around predicate registers"),
69 cl::init(true));
70static cl::opt<bool> ErrorMissingParenthesis(
71 "merror-missing-parenthesis",
72 cl::desc("Error for missing parenthesis around predicate registers"),
73 cl::init(false));
74static cl::opt<bool> WarnSignedMismatch(
75 "mwarn-sign-mismatch",
76 cl::desc("Warn for mismatching a signed and unsigned value"),
77 cl::init(true));
78static cl::opt<bool> WarnNoncontigiousRegister(
79 "mwarn-noncontigious-register",
80 cl::desc("Warn for register names that arent contigious"), cl::init(true));
81static cl::opt<bool> ErrorNoncontigiousRegister(
82 "merror-noncontigious-register",
83 cl::desc("Error for register names that aren't contigious"),
84 cl::init(false));
Colin LeMahieu7cd08922015-11-09 04:07:48 +000085
Colin LeMahieu7cd08922015-11-09 04:07:48 +000086namespace {
Eugene Zelenko82085922016-12-13 22:13:50 +000087
Colin LeMahieu7cd08922015-11-09 04:07:48 +000088struct HexagonOperand;
89
90class HexagonAsmParser : public MCTargetAsmParser {
91
92 HexagonTargetStreamer &getTargetStreamer() {
93 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
94 return static_cast<HexagonTargetStreamer &>(TS);
95 }
96
Colin LeMahieu7cd08922015-11-09 04:07:48 +000097 MCAsmParser &Parser;
98 MCAssembler *Assembler;
99 MCInstrInfo const &MCII;
100 MCInst MCB;
101 bool InBrackets;
102
103 MCAsmParser &getParser() const { return Parser; }
104 MCAssembler *getAssembler() const { return Assembler; }
105 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
106
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000107 bool equalIsAsmAssignment() override { return false; }
108 bool isLabel(AsmToken &Token) override;
109
110 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
111 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
112 bool ParseDirectiveFalign(unsigned Size, SMLoc L);
113
Eugene Zelenko82085922016-12-13 22:13:50 +0000114 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000115 bool ParseDirectiveSubsection(SMLoc L);
116 bool ParseDirectiveValue(unsigned Size, SMLoc L);
117 bool ParseDirectiveComm(bool IsLocal, SMLoc L);
118 bool RegisterMatchesArch(unsigned MatchNum) const;
119
120 bool matchBundleOptions();
121 bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
122 bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
123 void canonicalizeImmediates(MCInst &MCI);
124 bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
125 OperandVector &InstOperands, uint64_t &ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000126 bool MatchingInlineAsm);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000127
128 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
129 OperandVector &Operands, MCStreamer &Out,
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000130 uint64_t &ErrorInfo,
131 bool MatchingInlineAsm) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000132
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000133 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
134 unsigned Kind) override;
Nirav Dave2364748a2016-09-16 18:30:20 +0000135 bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000136 int processInstruction(MCInst &Inst, OperandVector const &Operands,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000137 SMLoc IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000138
139 // Check if we have an assembler and, if so, set the ELF e_header flags.
140 void chksetELFHeaderEFlags(unsigned flags) {
141 if (getAssembler())
142 getAssembler()->setELFHeaderEFlags(flags);
143 }
144
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +0000145 unsigned matchRegister(StringRef Name);
146
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000147/// @name Auto-generated Match Functions
148/// {
149
150#define GET_ASSEMBLER_HEADER
151#include "HexagonGenAsmMatcher.inc"
152
153 /// }
154
155public:
Akira Hatanakab11ef082015-11-14 06:35:56 +0000156 HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000157 const MCInstrInfo &MII, const MCTargetOptions &Options)
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000158 : MCTargetAsmParser(Options, _STI), Parser(_Parser),
Colin LeMahieuf0af6e52015-11-13 17:42:46 +0000159 MCII (MII), MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) {
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000160 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000161
Eugene Zelenko82085922016-12-13 22:13:50 +0000162 MCAsmParserExtension::Initialize(_Parser);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000163
Eugene Zelenko82085922016-12-13 22:13:50 +0000164 Assembler = nullptr;
165 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
166 if (!Parser.getStreamer().hasRawTextSupport()) {
167 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
168 Assembler = &MES->getAssembler();
169 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000170 }
171
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000172 bool splitIdentifier(OperandVector &Operands);
173 bool parseOperand(OperandVector &Operands);
174 bool parseInstruction(OperandVector &Operands);
175 bool implicitExpressionLocation(OperandVector &Operands);
176 bool parseExpressionOrOperand(OperandVector &Operands);
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000177 bool parseExpression(MCExpr const *&Expr);
Eugene Zelenko82085922016-12-13 22:13:50 +0000178
179 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000180 SMLoc NameLoc, OperandVector &Operands) override {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000181 llvm_unreachable("Unimplemented");
182 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000183
Eugene Zelenko82085922016-12-13 22:13:50 +0000184 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
185 OperandVector &Operands) override;
186
187 bool ParseDirective(AsmToken DirectiveID) override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000188};
189
190/// HexagonOperand - Instances of this class represent a parsed Hexagon machine
191/// instruction.
192struct HexagonOperand : public MCParsedAsmOperand {
193 enum KindTy { Token, Immediate, Register } Kind;
194
195 SMLoc StartLoc, EndLoc;
196
197 struct TokTy {
198 const char *Data;
199 unsigned Length;
200 };
201
202 struct RegTy {
203 unsigned RegNum;
204 };
205
206 struct ImmTy {
207 const MCExpr *Val;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000208 };
209
210 struct InstTy {
211 OperandVector *SubInsts;
212 };
213
214 union {
215 struct TokTy Tok;
216 struct RegTy Reg;
217 struct ImmTy Imm;
218 };
219
220 HexagonOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
221
222public:
223 HexagonOperand(const HexagonOperand &o) : MCParsedAsmOperand() {
224 Kind = o.Kind;
225 StartLoc = o.StartLoc;
226 EndLoc = o.EndLoc;
227 switch (Kind) {
228 case Register:
229 Reg = o.Reg;
230 break;
231 case Immediate:
232 Imm = o.Imm;
233 break;
234 case Token:
235 Tok = o.Tok;
236 break;
237 }
238 }
239
240 /// getStartLoc - Get the location of the first token of this operand.
Eugene Zelenko82085922016-12-13 22:13:50 +0000241 SMLoc getStartLoc() const override { return StartLoc; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000242
243 /// getEndLoc - Get the location of the last token of this operand.
Eugene Zelenko82085922016-12-13 22:13:50 +0000244 SMLoc getEndLoc() const override { return EndLoc; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000245
Eugene Zelenko82085922016-12-13 22:13:50 +0000246 unsigned getReg() const override {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000247 assert(Kind == Register && "Invalid access!");
248 return Reg.RegNum;
249 }
250
251 const MCExpr *getImm() const {
252 assert(Kind == Immediate && "Invalid access!");
253 return Imm.Val;
254 }
255
Eugene Zelenko82085922016-12-13 22:13:50 +0000256 bool isToken() const override { return Kind == Token; }
257 bool isImm() const override { return Kind == Immediate; }
258 bool isMem() const override { llvm_unreachable("No isMem"); }
259 bool isReg() const override { return Kind == Register; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000260
261 bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
262 bool isRelocatable, bool Extendable) const {
263 if (Kind == Immediate) {
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000264 const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000265 if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000266 return false;
267 int64_t Res;
268 if (myMCExpr->evaluateAsAbsolute(Res)) {
269 int bits = immBits + zeroBits;
270 // Field bit range is zerobits + bits
271 // zeroBits must be 0
272 if (Res & ((1 << zeroBits) - 1))
273 return false;
274 if (isSigned) {
275 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
276 return true;
277 } else {
278 if (bits == 64)
279 return true;
280 if (Res >= 0)
Eugene Zelenko82085922016-12-13 22:13:50 +0000281 return ((uint64_t)Res < (uint64_t)(1ULL << bits));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000282 else {
283 const int64_t high_bit_set = 1ULL << 63;
284 const uint64_t mask = (high_bit_set >> (63 - bits));
Eugene Zelenko82085922016-12-13 22:13:50 +0000285 return (((uint64_t)Res & mask) == mask);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000286 }
287 }
288 } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
289 return true;
290 else if (myMCExpr->getKind() == MCExpr::Binary ||
291 myMCExpr->getKind() == MCExpr::Unary)
292 return true;
293 }
294 return false;
295 }
296
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000297 bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
298 bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
299 bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
300 bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }
301
302 bool ism32_0Imm() const { return true; }
303
304 bool isf32Imm() const { return false; }
305 bool isf64Imm() const { return false; }
306 bool iss32_0Imm() const { return true; }
307 bool iss31_1Imm() const { return true; }
308 bool iss30_2Imm() const { return true; }
309 bool iss29_3Imm() const { return true; }
Colin LeMahieuecef1d92016-02-16 20:38:17 +0000310 bool iss23_2Imm() const { return CheckImmRange(23, 2, true, true, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000311 bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }
312 bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, false); }
313 bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000314 bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
315 bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
316 bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
317 bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000318 bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000319 bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
320 bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
321 bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
322 bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
323 bool iss4_6Imm() const { return CheckImmRange(4, 0, true, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000324 bool iss4_7Imm() const { return CheckImmRange(4, 0, true, false, false); }
325 bool iss3_7Imm() const { return CheckImmRange(3, 0, true, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000326 bool iss3_6Imm() const { return CheckImmRange(3, 0, true, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000327 bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000328
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000329 bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000330 bool isu32_0Imm() const { return true; }
331 bool isu31_1Imm() const { return true; }
332 bool isu30_2Imm() const { return true; }
333 bool isu29_3Imm() const { return true; }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000334 bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000335 bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
336 bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
337 bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
338 bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
339 bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000340 bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
341 bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
342 bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
343 bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
344 bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000345 bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
346 bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
347 bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000348 bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000349 bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
350 bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000351 bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000352 bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000353 bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000354 bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000355 bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
356 bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000357
Colin LeMahieu81707542016-12-05 04:29:00 +0000358 bool isn1Const() const {
359 if (!isImm())
360 return false;
361 int64_t Value;
362 if (!getImm()->evaluateAsAbsolute(Value))
363 return false;
364 return Value == -1;
365 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000366 bool iss11_0Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000367 return CheckImmRange(11 + 26, 0, true, true, true);
368 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000369 bool iss11_1Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000370 return CheckImmRange(11 + 26, 1, true, true, true);
371 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000372 bool iss11_2Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000373 return CheckImmRange(11 + 26, 2, true, true, true);
374 }
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000375 bool iss11_3Imm() const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000376 return CheckImmRange(11 + 26, 3, true, true, true);
377 }
Krzysztof Parzyszek654dc112016-11-01 19:02:10 +0000378 bool isu32_0MustExt() const { return isImm(); }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000379
380 void addRegOperands(MCInst &Inst, unsigned N) const {
381 assert(N == 1 && "Invalid number of operands!");
382 Inst.addOperand(MCOperand::createReg(getReg()));
383 }
384
385 void addImmOperands(MCInst &Inst, unsigned N) const {
386 assert(N == 1 && "Invalid number of operands!");
387 Inst.addOperand(MCOperand::createExpr(getImm()));
388 }
389
390 void addSignedImmOperands(MCInst &Inst, unsigned N) const {
391 assert(N == 1 && "Invalid number of operands!");
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000392 HexagonMCExpr *Expr =
393 const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000394 int64_t Value;
395 if (!Expr->evaluateAsAbsolute(Value)) {
396 Inst.addOperand(MCOperand::createExpr(Expr));
397 return;
398 }
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000399 int64_t Extended = SignExtend64(Value, 32);
400 if ((Extended < 0) != (Value < 0))
401 Expr->setSignMismatch();
402 Inst.addOperand(MCOperand::createExpr(Expr));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000403 }
404
Colin LeMahieu81707542016-12-05 04:29:00 +0000405 void addn1ConstOperands(MCInst &Inst, unsigned N) const {
406 addImmOperands(Inst, N);
407 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000408
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000409 void adds4_6ImmOperands(MCInst &Inst, unsigned N) const {
410 assert(N == 1 && "Invalid number of operands!");
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000411 const MCConstantExpr *CE =
412 dyn_cast<MCConstantExpr>(&HexagonMCInstrInfo::getExpr(*getImm()));
Colin LeMahieu4c606e62015-12-04 15:48:45 +0000413 Inst.addOperand(MCOperand::createImm(CE->getValue() * 64));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000414 }
415
416 void adds3_6ImmOperands(MCInst &Inst, unsigned N) const {
417 assert(N == 1 && "Invalid number of operands!");
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000418 const MCConstantExpr *CE =
419 dyn_cast<MCConstantExpr>(&HexagonMCInstrInfo::getExpr(*getImm()));
Colin LeMahieu4c606e62015-12-04 15:48:45 +0000420 Inst.addOperand(MCOperand::createImm(CE->getValue() * 64));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000421 }
422
423 StringRef getToken() const {
424 assert(Kind == Token && "Invalid access!");
425 return StringRef(Tok.Data, Tok.Length);
426 }
427
Eugene Zelenko82085922016-12-13 22:13:50 +0000428 void print(raw_ostream &OS) const override;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000429
430 static std::unique_ptr<HexagonOperand> CreateToken(StringRef Str, SMLoc S) {
431 HexagonOperand *Op = new HexagonOperand(Token);
432 Op->Tok.Data = Str.data();
433 Op->Tok.Length = Str.size();
434 Op->StartLoc = S;
435 Op->EndLoc = S;
436 return std::unique_ptr<HexagonOperand>(Op);
437 }
438
439 static std::unique_ptr<HexagonOperand> CreateReg(unsigned RegNum, SMLoc S,
440 SMLoc E) {
441 HexagonOperand *Op = new HexagonOperand(Register);
442 Op->Reg.RegNum = RegNum;
443 Op->StartLoc = S;
444 Op->EndLoc = E;
445 return std::unique_ptr<HexagonOperand>(Op);
446 }
447
448 static std::unique_ptr<HexagonOperand> CreateImm(const MCExpr *Val, SMLoc S,
449 SMLoc E) {
450 HexagonOperand *Op = new HexagonOperand(Immediate);
451 Op->Imm.Val = Val;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000452 Op->StartLoc = S;
453 Op->EndLoc = E;
454 return std::unique_ptr<HexagonOperand>(Op);
455 }
456};
457
Eugene Zelenko82085922016-12-13 22:13:50 +0000458} // end anonymous namespace
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000459
460void HexagonOperand::print(raw_ostream &OS) const {
461 switch (Kind) {
462 case Immediate:
463 getImm()->print(OS, nullptr);
464 break;
465 case Register:
466 OS << "<register R";
467 OS << getReg() << ">";
468 break;
469 case Token:
470 OS << "'" << getToken() << "'";
471 break;
472 }
473}
474
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000475bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
476 DEBUG(dbgs() << "Bundle:");
477 DEBUG(MCB.dump_pretty(dbgs()));
478 DEBUG(dbgs() << "--\n");
479
480 // Check the bundle for errors.
481 const MCRegisterInfo *RI = getContext().getRegisterInfo();
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000482 HexagonMCChecker Check(MCII, getSTI(), MCB, MCB, *RI);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000483
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000484 bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MCII, getSTI(),
485 getContext(), MCB,
486 &Check);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000487
Eugene Zelenko82085922016-12-13 22:13:50 +0000488 while (Check.getNextErrInfo()) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000489 unsigned Reg = Check.getErrRegister();
490 Twine R(RI->getName(Reg));
491
492 uint64_t Err = Check.getError();
493 if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
494 if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000495 return Error(
496 IDLoc,
497 "unconditional branch cannot precede another branch in packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000498
499 if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
500 HexagonMCErrInfo::CHECK_ERROR_NEWV & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000501 return Error(IDLoc, "register `" + R +
502 "' used with `.new' "
503 "but not validly modified in the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000504
505 if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000506 return Error(IDLoc, "register `" + R + "' modified more than once");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000507
508 if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000509 return Error(IDLoc, "cannot write to read-only register `" + R + "'");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000510
511 if (HexagonMCErrInfo::CHECK_ERROR_LOOP & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000512 return Error(IDLoc, "loop-setup and some branch instructions "
513 "cannot be in the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000514
515 if (HexagonMCErrInfo::CHECK_ERROR_ENDLOOP & Err) {
516 Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
Nirav Dave2364748a2016-09-16 18:30:20 +0000517 return Error(IDLoc,
518 "packet marked with `:endloop" + N + "' " +
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000519 "cannot contain instructions that modify register " +
520 "`" + R + "'");
521 }
522
523 if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000524 return Error(
525 IDLoc,
526 "instruction cannot appear in packet with other instructions");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000527
528 if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
Nirav Dave2364748a2016-09-16 18:30:20 +0000529 return Error(IDLoc, "too many slots used in packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000530
531 if (Err & HexagonMCErrInfo::CHECK_ERROR_SHUFFLE) {
532 uint64_t Erm = Check.getShuffleError();
533
534 if (HexagonShuffler::SHUFFLE_ERROR_INVALID == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000535 return Error(IDLoc, "invalid instruction packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000536 else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000537 return Error(IDLoc, "invalid instruction packet: too many stores");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000538 else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000539 return Error(IDLoc, "invalid instruction packet: too many loads");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000540 else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000541 return Error(IDLoc, "too many branches in packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000542 else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000543 return Error(IDLoc, "invalid instruction packet: out of slots");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000544 else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000545 return Error(IDLoc, "invalid instruction packet: slot error");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000546 else if (HexagonShuffler::SHUFFLE_ERROR_ERRATA2 == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000547 return Error(IDLoc, "v60 packet violation");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000548 else if (HexagonShuffler::SHUFFLE_ERROR_STORE_LOAD_CONFLICT == Erm)
Nirav Dave2364748a2016-09-16 18:30:20 +0000549 return Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000550 else
Nirav Dave2364748a2016-09-16 18:30:20 +0000551 return Error(IDLoc, "unknown error in instruction packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000552 }
553 }
554
555 unsigned Warn = Check.getWarning();
556 if (Warn != HexagonMCErrInfo::CHECK_SUCCESS) {
557 if (HexagonMCErrInfo::CHECK_WARN_CURRENT & Warn)
558 Warning(IDLoc, "register `" + R + "' used with `.cur' "
559 "but not used in the same packet");
560 else if (HexagonMCErrInfo::CHECK_WARN_TEMPORARY & Warn)
561 Warning(IDLoc, "register `" + R + "' used with `.tmp' "
562 "but not used in the same packet");
563 }
564 }
565
566 if (CheckOk) {
567 MCB.setLoc(IDLoc);
568 if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
569 assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
570 assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
571 // Empty packets are valid yet aren't emitted
572 return false;
573 }
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000574 Out.EmitInstruction(MCB, getSTI());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000575 } else {
576 // If compounding and duplexing didn't reduce the size below
577 // 4 or less we have a packet that is too big.
578 if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
579 Error(IDLoc, "invalid instruction packet: out of slots");
580 return true; // Error
581 }
582 }
583
584 return false; // No error
585}
586
587bool HexagonAsmParser::matchBundleOptions() {
588 MCAsmParser &Parser = getParser();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000589 while (true) {
590 if (!Parser.getTok().is(AsmToken::Colon))
591 return false;
Nirav Davefd910412016-06-17 16:06:17 +0000592 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000593 StringRef Option = Parser.getTok().getString();
594 if (Option.compare_lower("endloop0") == 0)
595 HexagonMCInstrInfo::setInnerLoop(MCB);
596 else if (Option.compare_lower("endloop1") == 0)
597 HexagonMCInstrInfo::setOuterLoop(MCB);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000598 else
599 return true;
Nirav Davefd910412016-06-17 16:06:17 +0000600 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000601 }
602}
603
604// For instruction aliases, immediates are generated rather than
605// MCConstantExpr. Convert them for uniform MCExpr.
606// Also check for signed/unsigned mismatches and warn
607void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
608 MCInst NewInst;
609 NewInst.setOpcode(MCI.getOpcode());
610 for (MCOperand &I : MCI)
611 if (I.isImm()) {
612 int64_t Value (I.getImm());
Colin LeMahieuc7b21242016-02-15 18:47:55 +0000613 NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000614 MCConstantExpr::create(Value, getContext()), getContext())));
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +0000615 } else {
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000616 if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
617 WarnSignedMismatch)
618 Warning (MCI.getLoc(), "Signed/Unsigned mismatch");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000619 NewInst.addOperand(I);
Colin LeMahieub9f1eae2016-02-29 19:17:56 +0000620 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000621 MCI = NewInst;
622}
623
624bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
625 OperandVector &InstOperands,
626 uint64_t &ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000627 bool MatchingInlineAsm) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000628 // Perform matching with tablegen asmmatcher generated function
629 int result =
630 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
631 if (result == Match_Success) {
632 MCI.setLoc(IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000633 canonicalizeImmediates(MCI);
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000634 result = processInstruction(MCI, InstOperands, IDLoc);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000635
636 DEBUG(dbgs() << "Insn:");
637 DEBUG(MCI.dump_pretty(dbgs()));
638 DEBUG(dbgs() << "\n\n");
639
640 MCI.setLoc(IDLoc);
641 }
642
643 // Create instruction operand for bundle instruction
644 // Break this into a separate function Code here is less readable
645 // Think about how to get an instruction error to report correctly.
646 // SMLoc will return the "{"
647 switch (result) {
648 default:
649 break;
650 case Match_Success:
651 return false;
652 case Match_MissingFeature:
653 return Error(IDLoc, "invalid instruction");
654 case Match_MnemonicFail:
655 return Error(IDLoc, "unrecognized instruction");
656 case Match_InvalidOperand:
657 SMLoc ErrorLoc = IDLoc;
658 if (ErrorInfo != ~0U) {
659 if (ErrorInfo >= InstOperands.size())
660 return Error(IDLoc, "too few operands for instruction");
661
662 ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
663 ->getStartLoc();
664 if (ErrorLoc == SMLoc())
665 ErrorLoc = IDLoc;
666 }
667 return Error(ErrorLoc, "invalid operand for instruction");
668 }
669 llvm_unreachable("Implement any new match types added!");
670}
671
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000672bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
673 OperandVector &Operands,
674 MCStreamer &Out,
675 uint64_t &ErrorInfo,
676 bool MatchingInlineAsm) {
677 if (!InBrackets) {
678 MCB.clear();
679 MCB.addOperand(MCOperand::createImm(0));
680 }
681 HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
682 if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
683 assert(Operands.size() == 1 && "Brackets should be by themselves");
684 if (InBrackets) {
685 getParser().Error(IDLoc, "Already in a packet");
686 return true;
687 }
688 InBrackets = true;
689 return false;
690 }
691 if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
692 assert(Operands.size() == 1 && "Brackets should be by themselves");
693 if (!InBrackets) {
694 getParser().Error(IDLoc, "Not in a packet");
695 return true;
696 }
697 InBrackets = false;
698 if (matchBundleOptions())
699 return true;
700 return finishBundle(IDLoc, Out);
701 }
702 MCInst *SubInst = new (getParser().getContext()) MCInst;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000703 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000704 MatchingInlineAsm))
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000705 return true;
706 HexagonMCInstrInfo::extendIfNeeded(
Colin LeMahieu73cd6862016-02-29 18:39:51 +0000707 getParser().getContext(), MCII, MCB, *SubInst);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000708 MCB.addOperand(MCOperand::createInst(SubInst));
709 if (!InBrackets)
710 return finishBundle(IDLoc, Out);
711 return false;
712}
713
714/// ParseDirective parses the Hexagon specific directives
715bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
716 StringRef IDVal = DirectiveID.getIdentifier();
717 if ((IDVal.lower() == ".word") || (IDVal.lower() == ".4byte"))
718 return ParseDirectiveValue(4, DirectiveID.getLoc());
719 if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
720 IDVal.lower() == ".half")
721 return ParseDirectiveValue(2, DirectiveID.getLoc());
722 if (IDVal.lower() == ".falign")
723 return ParseDirectiveFalign(256, DirectiveID.getLoc());
724 if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
725 return ParseDirectiveComm(true, DirectiveID.getLoc());
726 if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
727 return ParseDirectiveComm(false, DirectiveID.getLoc());
728 if (IDVal.lower() == ".subsection")
729 return ParseDirectiveSubsection(DirectiveID.getLoc());
730
731 return true;
732}
733bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
Eugene Zelenko82085922016-12-13 22:13:50 +0000734 const MCExpr *Subsection = nullptr;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000735 int64_t Res;
736
737 assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
738 "Invalid subsection directive");
739 getParser().parseExpression(Subsection);
740
741 if (!Subsection->evaluateAsAbsolute(Res))
742 return Error(L, "Cannot evaluate subsection number");
743
744 if (getLexer().isNot(AsmToken::EndOfStatement))
745 return TokError("unexpected token in directive");
746
747 // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
748 // negative subsections together and in the same order but at the opposite
749 // end of the section. Only legacy hexagon-gcc created assembly code
750 // used negative subsections.
751 if ((Res < 0) && (Res > -8193))
Colin LeMahieuc7b21242016-02-15 18:47:55 +0000752 Subsection = HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +0000753 MCConstantExpr::create(8192 + Res, getContext()), getContext());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000754
755 getStreamer().SubSection(Subsection);
756 return false;
757}
758
759/// ::= .falign [expression]
760bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
761
762 int64_t MaxBytesToFill = 15;
763
Simon Pilgrim6ba672e2016-11-17 19:21:20 +0000764 // if there is an argument
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000765 if (getLexer().isNot(AsmToken::EndOfStatement)) {
766 const MCExpr *Value;
767 SMLoc ExprLoc = L;
768
769 // Make sure we have a number (false is returned if expression is a number)
Eugene Zelenko82085922016-12-13 22:13:50 +0000770 if (!getParser().parseExpression(Value)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000771 // Make sure this is a number that is in range
772 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
773 uint64_t IntValue = MCE->getValue();
774 if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
775 return Error(ExprLoc, "literal value out of range (256) for falign");
776 MaxBytesToFill = IntValue;
777 Lex();
778 } else {
779 return Error(ExprLoc, "not a valid expression for falign directive");
780 }
781 }
782
783 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
784 Lex();
785
786 return false;
787}
788
789/// ::= .word [ expression (, expression)* ]
790bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L) {
791 if (getLexer().isNot(AsmToken::EndOfStatement)) {
Eugene Zelenko82085922016-12-13 22:13:50 +0000792 while (true) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000793 const MCExpr *Value;
794 SMLoc ExprLoc = L;
795 if (getParser().parseExpression(Value))
796 return true;
797
798 // Special case constant expressions to match code generator.
799 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
800 assert(Size <= 8 && "Invalid size");
801 uint64_t IntValue = MCE->getValue();
802 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
803 return Error(ExprLoc, "literal value out of range for directive");
804 getStreamer().EmitIntValue(IntValue, Size);
805 } else
806 getStreamer().EmitValue(Value, Size);
807
808 if (getLexer().is(AsmToken::EndOfStatement))
809 break;
810
811 // FIXME: Improve diagnostic.
812 if (getLexer().isNot(AsmToken::Comma))
813 return TokError("unexpected token in directive");
814 Lex();
815 }
816 }
817
818 Lex();
819 return false;
820}
821
822// This is largely a copy of AsmParser's ParseDirectiveComm extended to
823// accept a 3rd argument, AccessAlignment which indicates the smallest
824// memory access made to the symbol, expressed in bytes. If no
825// AccessAlignment is specified it defaults to the Alignment Value.
826// Hexagon's .lcomm:
827// .lcomm Symbol, Length, Alignment, AccessAlignment
828bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
829 // FIXME: need better way to detect if AsmStreamer (upstream removed
830 // getKind())
831 if (getStreamer().hasRawTextSupport())
832 return true; // Only object file output requires special treatment.
833
834 StringRef Name;
835 if (getParser().parseIdentifier(Name))
836 return TokError("expected identifier in directive");
837 // Handle the identifier as the key symbol.
838 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
839
840 if (getLexer().isNot(AsmToken::Comma))
841 return TokError("unexpected token in directive");
842 Lex();
843
844 int64_t Size;
845 SMLoc SizeLoc = getLexer().getLoc();
846 if (getParser().parseAbsoluteExpression(Size))
847 return true;
848
849 int64_t ByteAlignment = 1;
850 SMLoc ByteAlignmentLoc;
851 if (getLexer().is(AsmToken::Comma)) {
852 Lex();
853 ByteAlignmentLoc = getLexer().getLoc();
854 if (getParser().parseAbsoluteExpression(ByteAlignment))
855 return true;
856 if (!isPowerOf2_64(ByteAlignment))
857 return Error(ByteAlignmentLoc, "alignment must be a power of 2");
858 }
859
860 int64_t AccessAlignment = 0;
861 if (getLexer().is(AsmToken::Comma)) {
862 // The optional access argument specifies the size of the smallest memory
863 // access to be made to the symbol, expressed in bytes.
864 SMLoc AccessAlignmentLoc;
865 Lex();
866 AccessAlignmentLoc = getLexer().getLoc();
867 if (getParser().parseAbsoluteExpression(AccessAlignment))
868 return true;
869
870 if (!isPowerOf2_64(AccessAlignment))
871 return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
872 }
873
874 if (getLexer().isNot(AsmToken::EndOfStatement))
875 return TokError("unexpected token in '.comm' or '.lcomm' directive");
876
877 Lex();
878
879 // NOTE: a size of zero for a .comm should create a undefined symbol
880 // but a size of .lcomm creates a bss symbol of size zero.
881 if (Size < 0)
882 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
883 "be less than zero");
884
885 // NOTE: The alignment in the directive is a power of 2 value, the assembler
886 // may internally end up wanting an alignment in bytes.
887 // FIXME: Diagnose overflow.
888 if (ByteAlignment < 0)
889 return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
890 "alignment, can't be less than zero");
891
892 if (!Sym->isUndefined())
893 return Error(Loc, "invalid symbol redefinition");
894
895 HexagonMCELFStreamer &HexagonELFStreamer =
896 static_cast<HexagonMCELFStreamer &>(getStreamer());
897 if (IsLocal) {
898 HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
899 AccessAlignment);
900 return false;
901 }
902
903 HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
904 AccessAlignment);
905 return false;
906}
907
908// validate register against architecture
909bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
Krzysztof Parzyszekf9015e62017-02-10 23:46:45 +0000910 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
911 if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
912 return false;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000913 return true;
914}
915
916// extern "C" void LLVMInitializeHexagonAsmLexer();
917
918/// Force static initialization.
919extern "C" void LLVMInitializeHexagonAsmParser() {
Mehdi Aminif42454b2016-10-09 23:00:34 +0000920 RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000921}
922
923#define GET_MATCHER_IMPLEMENTATION
924#define GET_REGISTER_MATCHER
925#include "HexagonGenAsmMatcher.inc"
926
Eugene Zelenko82085922016-12-13 22:13:50 +0000927static bool previousEqual(OperandVector &Operands, size_t Index,
928 StringRef String) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000929 if (Index >= Operands.size())
930 return false;
931 MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
932 if (!Operand.isToken())
933 return false;
934 return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
935}
Eugene Zelenko82085922016-12-13 22:13:50 +0000936
937static bool previousIsLoop(OperandVector &Operands, size_t Index) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000938 return previousEqual(Operands, Index, "loop0") ||
939 previousEqual(Operands, Index, "loop1") ||
940 previousEqual(Operands, Index, "sp1loop0") ||
941 previousEqual(Operands, Index, "sp2loop0") ||
942 previousEqual(Operands, Index, "sp3loop0");
943}
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000944
945bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
946 AsmToken const &Token = getParser().getTok();
947 StringRef String = Token.getString();
948 SMLoc Loc = Token.getLoc();
Nirav Davefd910412016-06-17 16:06:17 +0000949 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000950 do {
951 std::pair<StringRef, StringRef> HeadTail = String.split('.');
952 if (!HeadTail.first.empty())
953 Operands.push_back(HexagonOperand::CreateToken(HeadTail.first, Loc));
954 if (!HeadTail.second.empty())
955 Operands.push_back(HexagonOperand::CreateToken(
956 String.substr(HeadTail.first.size(), 1), Loc));
957 String = HeadTail.second;
958 } while (!String.empty());
959 return false;
960}
961
962bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
963 unsigned Register;
964 SMLoc Begin;
965 SMLoc End;
966 MCAsmLexer &Lexer = getLexer();
967 if (!ParseRegister(Register, Begin, End)) {
968 if (!ErrorMissingParenthesis)
969 switch (Register) {
970 default:
971 break;
972 case Hexagon::P0:
973 case Hexagon::P1:
974 case Hexagon::P2:
975 case Hexagon::P3:
976 if (previousEqual(Operands, 0, "if")) {
977 if (WarnMissingParenthesis)
978 Warning (Begin, "Missing parenthesis around predicate register");
979 static char const *LParen = "(";
980 static char const *RParen = ")";
981 Operands.push_back(HexagonOperand::CreateToken(LParen, Begin));
982 Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
Benjamin Kramer4ca41fd2016-06-12 17:30:47 +0000983 const AsmToken &MaybeDotNew = Lexer.getTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000984 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
985 MaybeDotNew.getString().equals_lower(".new"))
986 splitIdentifier(Operands);
987 Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
988 return false;
989 }
990 if (previousEqual(Operands, 0, "!") &&
991 previousEqual(Operands, 1, "if")) {
992 if (WarnMissingParenthesis)
993 Warning (Begin, "Missing parenthesis around predicate register");
994 static char const *LParen = "(";
995 static char const *RParen = ")";
996 Operands.insert(Operands.end () - 1,
997 HexagonOperand::CreateToken(LParen, Begin));
998 Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
Benjamin Kramer4ca41fd2016-06-12 17:30:47 +0000999 const AsmToken &MaybeDotNew = Lexer.getTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001000 if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
1001 MaybeDotNew.getString().equals_lower(".new"))
1002 splitIdentifier(Operands);
1003 Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
1004 return false;
1005 }
1006 break;
1007 }
1008 Operands.push_back(HexagonOperand::CreateReg(
1009 Register, Begin, End));
1010 return false;
1011 }
1012 return splitIdentifier(Operands);
1013}
1014
1015bool HexagonAsmParser::isLabel(AsmToken &Token) {
1016 MCAsmLexer &Lexer = getLexer();
1017 AsmToken const &Second = Lexer.getTok();
Krzysztof Parzyszekf9015e62017-02-10 23:46:45 +00001018 AsmToken Third = Lexer.peekTok();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001019 StringRef String = Token.getString();
1020 if (Token.is(AsmToken::TokenKind::LCurly) ||
1021 Token.is(AsmToken::TokenKind::RCurly))
1022 return false;
Krzysztof Parzyszekf9015e62017-02-10 23:46:45 +00001023 // special case for parsing vwhist256:sat
1024 if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
1025 Third.getString().lower() == "sat")
1026 return false;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001027 if (!Token.is(AsmToken::TokenKind::Identifier))
1028 return true;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001029 if (!matchRegister(String.lower()))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001030 return true;
Colin LeMahieu9d851f02015-11-09 21:06:28 +00001031 (void)Second;
1032 assert(Second.is(AsmToken::Colon));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001033 StringRef Raw (String.data(), Third.getString().data() - String.data() +
1034 Third.getString().size());
1035 std::string Collapsed = Raw;
Eugene Zelenko82085922016-12-13 22:13:50 +00001036 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001037 StringRef Whole = Collapsed;
1038 std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001039 if (!matchRegister(DotSplit.first.lower()))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001040 return true;
1041 return false;
1042}
1043
1044bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious, SMLoc &Loc) {
1045 if (!Contigious && ErrorNoncontigiousRegister) {
1046 Error(Loc, "Register name is not contigious");
1047 return true;
1048 }
1049 if (!Contigious && WarnNoncontigiousRegister)
1050 Warning(Loc, "Register name is not contigious");
1051 return false;
1052}
1053
1054bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
1055 MCAsmLexer &Lexer = getLexer();
1056 StartLoc = getLexer().getLoc();
1057 SmallVector<AsmToken, 5> Lookahead;
1058 StringRef RawString(Lexer.getTok().getString().data(), 0);
1059 bool Again = Lexer.is(AsmToken::Identifier);
1060 bool NeededWorkaround = false;
1061 while (Again) {
1062 AsmToken const &Token = Lexer.getTok();
1063 RawString = StringRef(RawString.data(),
1064 Token.getString().data() - RawString.data () +
1065 Token.getString().size());
1066 Lookahead.push_back(Token);
1067 Lexer.Lex();
1068 bool Contigious = Lexer.getTok().getString().data() ==
1069 Lookahead.back().getString().data() +
1070 Lookahead.back().getString().size();
1071 bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1072 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1073 Lexer.is(AsmToken::Colon);
1074 bool Workaround = Lexer.is(AsmToken::Colon) ||
1075 Lookahead.back().is(AsmToken::Colon);
1076 Again = (Contigious && Type) || (Workaround && Type);
1077 NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1078 }
1079 std::string Collapsed = RawString;
Eugene Zelenko82085922016-12-13 22:13:50 +00001080 Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001081 StringRef FullString = Collapsed;
1082 std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001083 unsigned DotReg = matchRegister(DotSplit.first.lower());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001084 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1085 if (DotSplit.second.empty()) {
1086 RegNo = DotReg;
1087 EndLoc = Lexer.getLoc();
1088 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1089 return true;
1090 return false;
1091 } else {
1092 RegNo = DotReg;
1093 size_t First = RawString.find('.');
1094 StringRef DotString (RawString.data() + First, RawString.size() - First);
1095 Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1096 EndLoc = Lexer.getLoc();
1097 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1098 return true;
1099 return false;
1100 }
1101 }
1102 std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001103 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001104 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1105 Lexer.UnLex(Lookahead.back());
1106 Lookahead.pop_back();
1107 Lexer.UnLex(Lookahead.back());
1108 Lookahead.pop_back();
1109 RegNo = ColonReg;
1110 EndLoc = Lexer.getLoc();
1111 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1112 return true;
1113 return false;
1114 }
1115 while (!Lookahead.empty()) {
1116 Lexer.UnLex(Lookahead.back());
1117 Lookahead.pop_back();
1118 }
1119 return true;
1120}
1121
1122bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1123 if (previousEqual(Operands, 0, "call"))
1124 return true;
1125 if (previousEqual(Operands, 0, "jump"))
1126 if (!getLexer().getTok().is(AsmToken::Colon))
1127 return true;
1128 if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1129 return true;
1130 if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1131 (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1132 return true;
1133 return false;
1134}
1135
1136bool HexagonAsmParser::parseExpression(MCExpr const *& Expr) {
Eugene Zelenko82085922016-12-13 22:13:50 +00001137 SmallVector<AsmToken, 4> Tokens;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001138 MCAsmLexer &Lexer = getLexer();
1139 bool Done = false;
1140 static char const * Comma = ",";
1141 do {
1142 Tokens.emplace_back (Lexer.getTok());
Nirav Davefd910412016-06-17 16:06:17 +00001143 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001144 switch (Tokens.back().getKind())
1145 {
1146 case AsmToken::TokenKind::Hash:
1147 if (Tokens.size () > 1)
1148 if ((Tokens.end () - 2)->getKind() == AsmToken::TokenKind::Plus) {
1149 Tokens.insert(Tokens.end() - 2,
1150 AsmToken(AsmToken::TokenKind::Comma, Comma));
1151 Done = true;
1152 }
1153 break;
1154 case AsmToken::TokenKind::RCurly:
1155 case AsmToken::TokenKind::EndOfStatement:
1156 case AsmToken::TokenKind::Eof:
1157 Done = true;
1158 break;
1159 default:
1160 break;
1161 }
1162 } while (!Done);
1163 while (!Tokens.empty()) {
1164 Lexer.UnLex(Tokens.back());
1165 Tokens.pop_back();
1166 }
1167 return getParser().parseExpression(Expr);
1168}
1169
1170bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1171 if (implicitExpressionLocation(Operands)) {
1172 MCAsmParser &Parser = getParser();
1173 SMLoc Loc = Parser.getLexer().getLoc();
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001174 MCExpr const *Expr = nullptr;
1175 bool Error = parseExpression(Expr);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001176 Expr = HexagonMCExpr::create(Expr, getContext());
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001177 if (!Error)
1178 Operands.push_back(HexagonOperand::CreateImm(Expr, Loc, Loc));
1179 return Error;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001180 }
1181 return parseOperand(Operands);
1182}
1183
1184/// Parse an instruction.
1185bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1186 MCAsmParser &Parser = getParser();
1187 MCAsmLexer &Lexer = getLexer();
1188 while (true) {
1189 AsmToken const &Token = Parser.getTok();
1190 switch (Token.getKind()) {
1191 case AsmToken::EndOfStatement: {
Nirav Davefd910412016-06-17 16:06:17 +00001192 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001193 return false;
1194 }
1195 case AsmToken::LCurly: {
1196 if (!Operands.empty())
1197 return true;
1198 Operands.push_back(
1199 HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001200 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001201 return false;
1202 }
1203 case AsmToken::RCurly: {
1204 if (Operands.empty()) {
1205 Operands.push_back(
1206 HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001207 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001208 }
1209 return false;
1210 }
1211 case AsmToken::Comma: {
Nirav Davefd910412016-06-17 16:06:17 +00001212 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001213 continue;
1214 }
1215 case AsmToken::EqualEqual:
1216 case AsmToken::ExclaimEqual:
1217 case AsmToken::GreaterEqual:
1218 case AsmToken::GreaterGreater:
1219 case AsmToken::LessEqual:
1220 case AsmToken::LessLess: {
1221 Operands.push_back(HexagonOperand::CreateToken(
1222 Token.getString().substr(0, 1), Token.getLoc()));
1223 Operands.push_back(HexagonOperand::CreateToken(
1224 Token.getString().substr(1, 1), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001225 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001226 continue;
1227 }
1228 case AsmToken::Hash: {
1229 bool MustNotExtend = false;
1230 bool ImplicitExpression = implicitExpressionLocation(Operands);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001231 SMLoc ExprLoc = Lexer.getLoc();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001232 if (!ImplicitExpression)
1233 Operands.push_back(
1234 HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
Nirav Davefd910412016-06-17 16:06:17 +00001235 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001236 bool MustExtend = false;
1237 bool HiOnly = false;
1238 bool LoOnly = false;
1239 if (Lexer.is(AsmToken::Hash)) {
Nirav Davefd910412016-06-17 16:06:17 +00001240 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001241 MustExtend = true;
1242 } else if (ImplicitExpression)
1243 MustNotExtend = true;
1244 AsmToken const &Token = Parser.getTok();
1245 if (Token.is(AsmToken::Identifier)) {
1246 StringRef String = Token.getString();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001247 if (String.lower() == "hi") {
1248 HiOnly = true;
1249 } else if (String.lower() == "lo") {
1250 LoOnly = true;
1251 }
1252 if (HiOnly || LoOnly) {
1253 AsmToken LParen = Lexer.peekTok();
1254 if (!LParen.is(AsmToken::LParen)) {
1255 HiOnly = false;
1256 LoOnly = false;
1257 } else {
Nirav Davefd910412016-06-17 16:06:17 +00001258 Lex();
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001259 }
1260 }
1261 }
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001262 MCExpr const *Expr = nullptr;
1263 if (parseExpression(Expr))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001264 return true;
1265 int64_t Value;
1266 MCContext &Context = Parser.getContext();
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001267 assert(Expr != nullptr);
1268 if (Expr->evaluateAsAbsolute(Value)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001269 if (HiOnly)
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001270 Expr = MCBinaryExpr::createLShr(
1271 Expr, MCConstantExpr::create(16, Context), Context);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001272 if (HiOnly || LoOnly)
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001273 Expr = MCBinaryExpr::createAnd(Expr,
1274 MCConstantExpr::create(0xffff, Context),
1275 Context);
Colin LeMahieu5cb6eea2016-03-01 21:37:41 +00001276 } else {
1277 MCValue Value;
1278 if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1279 if (!Value.isAbsolute()) {
1280 switch(Value.getAccessVariant()) {
1281 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1282 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1283 // Don't lazy extend these expression variants
1284 MustNotExtend = !MustExtend;
1285 break;
1286 default:
1287 break;
1288 }
1289 }
1290 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001291 }
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001292 Expr = HexagonMCExpr::create(Expr, Context);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001293 HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001294 HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001295 std::unique_ptr<HexagonOperand> Operand =
1296 HexagonOperand::CreateImm(Expr, ExprLoc, ExprLoc);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001297 Operands.push_back(std::move(Operand));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001298 continue;
1299 }
1300 default:
1301 break;
1302 }
1303 if (parseExpressionOrOperand(Operands))
1304 return true;
1305 }
1306}
1307
1308bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1309 StringRef Name,
1310 AsmToken ID,
1311 OperandVector &Operands) {
1312 getLexer().UnLex(ID);
1313 return parseInstruction(Operands);
1314}
1315
Eugene Zelenko82085922016-12-13 22:13:50 +00001316static MCInst makeCombineInst(int opCode, MCOperand &Rdd,
1317 MCOperand &MO1, MCOperand &MO2) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001318 MCInst TmpInst;
1319 TmpInst.setOpcode(opCode);
1320 TmpInst.addOperand(Rdd);
1321 TmpInst.addOperand(MO1);
1322 TmpInst.addOperand(MO2);
1323
1324 return TmpInst;
1325}
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001326
1327// Define this matcher function after the auto-generated include so we
1328// have the match class enum definitions.
1329unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1330 unsigned Kind) {
1331 HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1332
1333 switch (Kind) {
1334 case MCK_0: {
1335 int64_t Value;
1336 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1337 ? Match_Success
1338 : Match_InvalidOperand;
1339 }
1340 case MCK_1: {
1341 int64_t Value;
1342 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1343 ? Match_Success
1344 : Match_InvalidOperand;
1345 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001346 }
1347 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1348 StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1349 if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1350 return Match_Success;
1351 if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1352 return Match_Success;
1353 }
1354
1355 DEBUG(dbgs() << "Unmatched Operand:");
1356 DEBUG(Op->dump());
1357 DEBUG(dbgs() << "\n");
1358
1359 return Match_InvalidOperand;
1360}
1361
Nirav Dave2364748a2016-09-16 18:30:20 +00001362// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1363bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001364 std::string errStr;
1365 raw_string_ostream ES(errStr);
Alexey Samsonov44ff2042015-12-02 22:59:22 +00001366 ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001367 if (Max >= 0)
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001368 ES << "0-" << Max;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001369 else
Alexey Samsonovbcfabaa2015-12-02 21:13:43 +00001370 ES << Max << "-" << (-Max - 1);
Malcolm Parsons06ac79c2016-11-02 16:43:50 +00001371 return Parser.printError(IDLoc, ES.str());
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001372}
1373
1374int HexagonAsmParser::processInstruction(MCInst &Inst,
1375 OperandVector const &Operands,
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001376 SMLoc IDLoc) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001377 MCContext &Context = getParser().getContext();
1378 const MCRegisterInfo *RI = getContext().getRegisterInfo();
1379 std::string r = "r";
1380 std::string v = "v";
1381 std::string Colon = ":";
1382
1383 bool is32bit = false; // used to distinguish between CONST32 and CONST64
1384 switch (Inst.getOpcode()) {
1385 default:
1386 break;
1387
Colin LeMahieuecef1d92016-02-16 20:38:17 +00001388 case Hexagon::A2_iconst: {
1389 Inst.setOpcode(Hexagon::A2_addi);
1390 MCOperand Reg = Inst.getOperand(0);
1391 MCOperand S16 = Inst.getOperand(1);
1392 HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
1393 HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
1394 Inst.clear();
1395 Inst.addOperand(Reg);
1396 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1397 Inst.addOperand(S16);
1398 break;
1399 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001400 case Hexagon::M4_mpyrr_addr:
1401 case Hexagon::S4_addi_asl_ri:
1402 case Hexagon::S4_addi_lsr_ri:
1403 case Hexagon::S4_andi_asl_ri:
1404 case Hexagon::S4_andi_lsr_ri:
1405 case Hexagon::S4_ori_asl_ri:
1406 case Hexagon::S4_ori_lsr_ri:
1407 case Hexagon::S4_or_andix:
1408 case Hexagon::S4_subi_asl_ri:
1409 case Hexagon::S4_subi_lsr_ri: {
1410 MCOperand &Ry = Inst.getOperand(0);
1411 MCOperand &src = Inst.getOperand(2);
1412 if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1413 return Match_InvalidOperand;
1414 break;
1415 }
1416
1417 case Hexagon::C2_cmpgei: {
1418 MCOperand &MO = Inst.getOperand(2);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001419 MO.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001420 MO.getExpr(), MCConstantExpr::create(1, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001421 Inst.setOpcode(Hexagon::C2_cmpgti);
1422 break;
1423 }
1424
1425 case Hexagon::C2_cmpgeui: {
1426 MCOperand &MO = Inst.getOperand(2);
1427 int64_t Value;
1428 bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
Colin LeMahieu9d851f02015-11-09 21:06:28 +00001429 (void)Success;
1430 assert(Success && "Assured by matcher");
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001431 if (Value == 0) {
1432 MCInst TmpInst;
1433 MCOperand &Pd = Inst.getOperand(0);
1434 MCOperand &Rt = Inst.getOperand(1);
1435 TmpInst.setOpcode(Hexagon::C2_cmpeq);
1436 TmpInst.addOperand(Pd);
1437 TmpInst.addOperand(Rt);
1438 TmpInst.addOperand(Rt);
1439 Inst = TmpInst;
1440 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001441 MO.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001442 MO.getExpr(), MCConstantExpr::create(1, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001443 Inst.setOpcode(Hexagon::C2_cmpgtui);
1444 }
1445 break;
1446 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001447
1448 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1449 case Hexagon::A2_tfrp: {
1450 MCOperand &MO = Inst.getOperand(1);
1451 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001452 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001453 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001454 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001455 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001456 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001457 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001458 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001459 Inst.setOpcode(Hexagon::A2_combinew);
1460 break;
1461 }
1462
1463 case Hexagon::A2_tfrpt:
1464 case Hexagon::A2_tfrpf: {
1465 MCOperand &MO = Inst.getOperand(2);
1466 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001467 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001468 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001469 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001470 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001471 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001472 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001473 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001474 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1475 ? Hexagon::C2_ccombinewt
1476 : Hexagon::C2_ccombinewf);
1477 break;
1478 }
1479 case Hexagon::A2_tfrptnew:
1480 case Hexagon::A2_tfrpfnew: {
1481 MCOperand &MO = Inst.getOperand(2);
1482 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001483 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001484 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001485 MO.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001486 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001487 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001488 StringRef Reg2(R2);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001489 Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001490 Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1491 ? Hexagon::C2_ccombinewnewt
1492 : Hexagon::C2_ccombinewnewf);
1493 break;
1494 }
1495
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001496 // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001497 case Hexagon::V6_vassignp: {
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001498 MCOperand &MO = Inst.getOperand(1);
1499 unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001500 std::string R1 = v + utostr(RegPairNum + 1);
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001501 MO.setReg(MatchRegisterName(R1));
1502 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001503 std::string R2 = v + utostr(RegPairNum);
Krzysztof Parzyszek0e7d2d32016-04-28 16:43:16 +00001504 Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
1505 Inst.setOpcode(Hexagon::V6_vcombine);
1506 break;
1507 }
1508
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001509 // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1510 case Hexagon::CONST32:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001511 is32bit = true;
1512 // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
Krzysztof Parzyszeka3386502016-08-10 16:46:36 +00001513 case Hexagon::CONST64:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001514 // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1515 if (!Parser.getStreamer().hasRawTextSupport()) {
1516 MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1517 MCOperand &MO_1 = Inst.getOperand(1);
1518 MCOperand &MO_0 = Inst.getOperand(0);
1519
1520 // push section onto section stack
1521 MES->PushSection();
1522
1523 std::string myCharStr;
1524 MCSectionELF *mySection;
1525
1526 // check if this as an immediate or a symbol
1527 int64_t Value;
1528 bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1529 if (Absolute) {
1530 // Create a new section - one for each constant
1531 // Some or all of the zeros are replaced with the given immediate.
1532 if (is32bit) {
1533 std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1534 myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1535 .drop_back(myImmStr.size())
1536 .str() +
1537 myImmStr;
1538 } else {
1539 std::string myImmStr = utohexstr(Value);
1540 myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1541 .drop_back(myImmStr.size())
1542 .str() +
1543 myImmStr;
1544 }
1545
1546 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1547 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1548 } else if (MO_1.isExpr()) {
1549 // .lita - for expressions
1550 myCharStr = ".lita";
1551 mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1552 ELF::SHF_ALLOC | ELF::SHF_WRITE);
1553 } else
1554 llvm_unreachable("unexpected type of machine operand!");
1555
1556 MES->SwitchSection(mySection);
1557 unsigned byteSize = is32bit ? 4 : 8;
1558 getStreamer().EmitCodeAlignment(byteSize, byteSize);
1559
1560 MCSymbol *Sym;
1561
1562 // for symbols, get rid of prepended ".gnu.linkonce.lx."
1563
1564 // emit symbol if needed
1565 if (Absolute) {
1566 Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1567 if (Sym->isUndefined()) {
1568 getStreamer().EmitLabel(Sym);
1569 getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1570 getStreamer().EmitIntValue(Value, byteSize);
1571 }
1572 } else if (MO_1.isExpr()) {
Eugene Zelenko82085922016-12-13 22:13:50 +00001573 const char *StringStart = nullptr;
1574 const char *StringEnd = nullptr;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001575 if (*Operands[4]->getStartLoc().getPointer() == '#') {
1576 StringStart = Operands[5]->getStartLoc().getPointer();
1577 StringEnd = Operands[6]->getStartLoc().getPointer();
1578 } else { // no pound
1579 StringStart = Operands[4]->getStartLoc().getPointer();
1580 StringEnd = Operands[5]->getStartLoc().getPointer();
1581 }
1582
1583 unsigned size = StringEnd - StringStart;
1584 std::string DotConst = ".CONST_";
1585 Sym = getContext().getOrCreateSymbol(DotConst +
1586 StringRef(StringStart, size));
1587
1588 if (Sym->isUndefined()) {
1589 // case where symbol is not yet defined: emit symbol
1590 getStreamer().EmitLabel(Sym);
1591 getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1592 getStreamer().EmitValue(MO_1.getExpr(), 4);
1593 }
1594 } else
1595 llvm_unreachable("unexpected type of machine operand!");
1596
1597 MES->PopSection();
1598
1599 if (Sym) {
1600 MCInst TmpInst;
1601 if (is32bit) // 32 bit
1602 TmpInst.setOpcode(Hexagon::L2_loadrigp);
1603 else // 64 bit
1604 TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1605
1606 TmpInst.addOperand(MO_0);
Krzysztof Parzyszekd0d42f02017-02-02 20:35:12 +00001607 TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
1608 MCSymbolRefExpr::create(Sym, getContext()), getContext())));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001609 Inst = TmpInst;
1610 }
1611 }
1612 break;
1613
1614 // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1615 case Hexagon::A2_tfrpi: {
1616 MCOperand &Rdd = Inst.getOperand(0);
1617 MCOperand &MO = Inst.getOperand(1);
1618 int64_t Value;
1619 int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001620 MCOperand imm(MCOperand::createExpr(
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001621 HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001622 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1623 break;
1624 }
1625
1626 // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1627 case Hexagon::TFRI64_V4: {
1628 MCOperand &Rdd = Inst.getOperand(0);
1629 MCOperand &MO = Inst.getOperand(1);
1630 int64_t Value;
1631 if (MO.getExpr()->evaluateAsAbsolute(Value)) {
David Majnemere61e4bf2016-06-21 05:10:24 +00001632 int s8 = Hi_32(Value);
1633 if (!isInt<8>(s8))
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001634 OutOfRange(IDLoc, s8, -128);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001635 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001636 MCConstantExpr::create(s8, Context), Context))); // upper 32
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001637 auto Expr = HexagonMCExpr::create(
David Majnemere61e4bf2016-06-21 05:10:24 +00001638 MCConstantExpr::create(Lo_32(Value), Context), Context);
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001639 HexagonMCInstrInfo::setMustExtend(*Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
1640 MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001641 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1642 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001643 MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001644 MCConstantExpr::create(0, Context), Context))); // upper 32
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001645 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1646 }
1647 break;
1648 }
1649
1650 // Handle $Rdd = combine(##imm, #imm)"
1651 case Hexagon::TFRI64_V2_ext: {
1652 MCOperand &Rdd = Inst.getOperand(0);
1653 MCOperand &MO1 = Inst.getOperand(1);
1654 MCOperand &MO2 = Inst.getOperand(2);
1655 int64_t Value;
1656 if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1657 int s8 = Value;
1658 if (s8 < -128 || s8 > 127)
1659 OutOfRange(IDLoc, s8, -128);
1660 }
1661 Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1662 break;
1663 }
1664
1665 // Handle $Rdd = combine(#imm, ##imm)"
1666 case Hexagon::A4_combineii: {
1667 MCOperand &Rdd = Inst.getOperand(0);
1668 MCOperand &MO1 = Inst.getOperand(1);
1669 int64_t Value;
1670 if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1671 int s8 = Value;
1672 if (s8 < -128 || s8 > 127)
1673 OutOfRange(IDLoc, s8, -128);
1674 }
1675 MCOperand &MO2 = Inst.getOperand(2);
1676 Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1677 break;
1678 }
1679
Eugene Zelenko82085922016-12-13 22:13:50 +00001680 case Hexagon::S2_tableidxb_goodsyntax:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001681 Inst.setOpcode(Hexagon::S2_tableidxb);
1682 break;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001683
1684 case Hexagon::S2_tableidxh_goodsyntax: {
1685 MCInst TmpInst;
1686 MCOperand &Rx = Inst.getOperand(0);
1687 MCOperand &_dst_ = Inst.getOperand(1);
1688 MCOperand &Rs = Inst.getOperand(2);
1689 MCOperand &Imm4 = Inst.getOperand(3);
1690 MCOperand &Imm6 = Inst.getOperand(4);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001691 Imm6.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001692 Imm6.getExpr(), MCConstantExpr::create(1, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001693 TmpInst.setOpcode(Hexagon::S2_tableidxh);
1694 TmpInst.addOperand(Rx);
1695 TmpInst.addOperand(_dst_);
1696 TmpInst.addOperand(Rs);
1697 TmpInst.addOperand(Imm4);
1698 TmpInst.addOperand(Imm6);
1699 Inst = TmpInst;
1700 break;
1701 }
1702
1703 case Hexagon::S2_tableidxw_goodsyntax: {
1704 MCInst TmpInst;
1705 MCOperand &Rx = Inst.getOperand(0);
1706 MCOperand &_dst_ = Inst.getOperand(1);
1707 MCOperand &Rs = Inst.getOperand(2);
1708 MCOperand &Imm4 = Inst.getOperand(3);
1709 MCOperand &Imm6 = Inst.getOperand(4);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001710 Imm6.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001711 Imm6.getExpr(), MCConstantExpr::create(2, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001712 TmpInst.setOpcode(Hexagon::S2_tableidxw);
1713 TmpInst.addOperand(Rx);
1714 TmpInst.addOperand(_dst_);
1715 TmpInst.addOperand(Rs);
1716 TmpInst.addOperand(Imm4);
1717 TmpInst.addOperand(Imm6);
1718 Inst = TmpInst;
1719 break;
1720 }
1721
1722 case Hexagon::S2_tableidxd_goodsyntax: {
1723 MCInst TmpInst;
1724 MCOperand &Rx = Inst.getOperand(0);
1725 MCOperand &_dst_ = Inst.getOperand(1);
1726 MCOperand &Rs = Inst.getOperand(2);
1727 MCOperand &Imm4 = Inst.getOperand(3);
1728 MCOperand &Imm6 = Inst.getOperand(4);
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001729 Imm6.setExpr(HexagonMCExpr::create(MCBinaryExpr::createSub(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001730 Imm6.getExpr(), MCConstantExpr::create(3, Context), Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001731 TmpInst.setOpcode(Hexagon::S2_tableidxd);
1732 TmpInst.addOperand(Rx);
1733 TmpInst.addOperand(_dst_);
1734 TmpInst.addOperand(Rs);
1735 TmpInst.addOperand(Imm4);
1736 TmpInst.addOperand(Imm6);
1737 Inst = TmpInst;
1738 break;
1739 }
1740
Eugene Zelenko82085922016-12-13 22:13:50 +00001741 case Hexagon::M2_mpyui:
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001742 Inst.setOpcode(Hexagon::M2_mpyi);
1743 break;
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001744 case Hexagon::M2_mpysmi: {
1745 MCInst TmpInst;
1746 MCOperand &Rd = Inst.getOperand(0);
1747 MCOperand &Rs = Inst.getOperand(1);
1748 MCOperand &Imm = Inst.getOperand(2);
1749 int64_t Value;
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001750 MCExpr const &Expr = *Imm.getExpr();
1751 bool Absolute = Expr.evaluateAsAbsolute(Value);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001752 assert(Absolute);
1753 (void)Absolute;
Colin LeMahieu73cd6862016-02-29 18:39:51 +00001754 if (!HexagonMCInstrInfo::mustExtend(Expr)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001755 if (Value < 0 && Value > -256) {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001756 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001757 MCConstantExpr::create(Value * -1, Context), Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001758 TmpInst.setOpcode(Hexagon::M2_mpysin);
1759 } else if (Value < 256 && Value >= 0)
1760 TmpInst.setOpcode(Hexagon::M2_mpysip);
1761 else
1762 return Match_InvalidOperand;
1763 } else {
1764 if (Value >= 0)
1765 TmpInst.setOpcode(Hexagon::M2_mpysip);
1766 else
1767 return Match_InvalidOperand;
1768 }
1769 TmpInst.addOperand(Rd);
1770 TmpInst.addOperand(Rs);
1771 TmpInst.addOperand(Imm);
1772 Inst = TmpInst;
1773 break;
1774 }
1775
1776 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1777 MCOperand &Imm = Inst.getOperand(2);
1778 MCInst TmpInst;
1779 int64_t Value;
1780 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1781 assert(Absolute);
1782 (void)Absolute;
1783 if (Value == 0) { // convert to $Rd = $Rs
1784 TmpInst.setOpcode(Hexagon::A2_tfr);
1785 MCOperand &Rd = Inst.getOperand(0);
1786 MCOperand &Rs = Inst.getOperand(1);
1787 TmpInst.addOperand(Rd);
1788 TmpInst.addOperand(Rs);
1789 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001790 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001791 MCBinaryExpr::createSub(Imm.getExpr(),
1792 MCConstantExpr::create(1, Context), Context),
1793 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001794 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1795 MCOperand &Rd = Inst.getOperand(0);
1796 MCOperand &Rs = Inst.getOperand(1);
1797 TmpInst.addOperand(Rd);
1798 TmpInst.addOperand(Rs);
1799 TmpInst.addOperand(Imm);
1800 }
1801 Inst = TmpInst;
1802 break;
1803 }
1804
1805 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1806 MCOperand &Rdd = Inst.getOperand(0);
1807 MCOperand &Rss = Inst.getOperand(1);
1808 MCOperand &Imm = Inst.getOperand(2);
1809 int64_t Value;
1810 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1811 assert(Absolute);
1812 (void)Absolute;
1813 if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1814 MCInst TmpInst;
1815 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001816 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001817 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001818 Rss.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001819 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001820 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001821 StringRef Reg2(R2);
1822 TmpInst.setOpcode(Hexagon::A2_combinew);
1823 TmpInst.addOperand(Rdd);
1824 TmpInst.addOperand(Rss);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001825 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001826 Inst = TmpInst;
1827 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001828 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001829 MCBinaryExpr::createSub(Imm.getExpr(),
1830 MCConstantExpr::create(1, Context), Context),
1831 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001832 Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1833 }
1834 break;
1835 }
1836
1837 case Hexagon::A4_boundscheck: {
1838 MCOperand &Rs = Inst.getOperand(1);
1839 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1840 if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1841 Inst.setOpcode(Hexagon::A4_boundscheck_hi);
Eugene Zelenko82085922016-12-13 22:13:50 +00001842 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001843 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001844 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001845 } else { // raw:lo
1846 Inst.setOpcode(Hexagon::A4_boundscheck_lo);
Eugene Zelenko82085922016-12-13 22:13:50 +00001847 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001848 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001849 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001850 }
1851 break;
1852 }
1853
1854 case Hexagon::A2_addsp: {
1855 MCOperand &Rs = Inst.getOperand(1);
1856 unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1857 if (RegNum & 1) { // Odd mapped to raw:hi
1858 Inst.setOpcode(Hexagon::A2_addsph);
Eugene Zelenko82085922016-12-13 22:13:50 +00001859 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001860 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001861 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001862 } else { // Even mapped raw:lo
1863 Inst.setOpcode(Hexagon::A2_addspl);
Eugene Zelenko82085922016-12-13 22:13:50 +00001864 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001865 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001866 Rs.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001867 }
1868 break;
1869 }
1870
1871 case Hexagon::M2_vrcmpys_s1: {
1872 MCOperand &Rt = Inst.getOperand(2);
1873 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1874 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1875 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00001876 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001877 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001878 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001879 } else { // Even mapped sat:raw:lo
1880 Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00001881 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001882 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001883 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001884 }
1885 break;
1886 }
1887
1888 case Hexagon::M2_vrcmpys_acc_s1: {
1889 MCInst TmpInst;
1890 MCOperand &Rxx = Inst.getOperand(0);
1891 MCOperand &Rss = Inst.getOperand(2);
1892 MCOperand &Rt = Inst.getOperand(3);
1893 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1894 if (RegNum & 1) { // Odd mapped to sat:raw:hi
1895 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00001896 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001897 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001898 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001899 } else { // Even mapped sat:raw:lo
1900 TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00001901 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001902 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001903 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001904 }
1905 // Registers are in different positions
1906 TmpInst.addOperand(Rxx);
1907 TmpInst.addOperand(Rxx);
1908 TmpInst.addOperand(Rss);
1909 TmpInst.addOperand(Rt);
1910 Inst = TmpInst;
1911 break;
1912 }
1913
1914 case Hexagon::M2_vrcmpys_s1rp: {
1915 MCOperand &Rt = Inst.getOperand(2);
1916 unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1917 if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
1918 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
Eugene Zelenko82085922016-12-13 22:13:50 +00001919 std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001920 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001921 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001922 } else { // Even mapped rnd:sat:raw:lo
1923 Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
Eugene Zelenko82085922016-12-13 22:13:50 +00001924 std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001925 StringRef RegPair = Name;
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001926 Rt.setReg(matchRegister(RegPair));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001927 }
1928 break;
1929 }
1930
1931 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1932 MCOperand &Imm = Inst.getOperand(2);
1933 int64_t Value;
1934 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1935 assert(Absolute);
1936 (void)Absolute;
1937 if (Value == 0)
1938 Inst.setOpcode(Hexagon::S2_vsathub);
1939 else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001940 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001941 MCBinaryExpr::createSub(Imm.getExpr(),
1942 MCConstantExpr::create(1, Context), Context),
1943 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001944 Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
1945 }
1946 break;
1947 }
1948
1949 case Hexagon::S5_vasrhrnd_goodsyntax: {
1950 MCOperand &Rdd = Inst.getOperand(0);
1951 MCOperand &Rss = Inst.getOperand(1);
1952 MCOperand &Imm = Inst.getOperand(2);
1953 int64_t Value;
1954 bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1955 assert(Absolute);
1956 (void)Absolute;
1957 if (Value == 0) {
1958 MCInst TmpInst;
1959 unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
Eugene Zelenko82085922016-12-13 22:13:50 +00001960 std::string R1 = r + utostr(RegPairNum + 1);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001961 StringRef Reg1(R1);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001962 Rss.setReg(matchRegister(Reg1));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001963 // Add a new operand for the second register in the pair.
Eugene Zelenko82085922016-12-13 22:13:50 +00001964 std::string R2 = r + utostr(RegPairNum);
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001965 StringRef Reg2(R2);
1966 TmpInst.setOpcode(Hexagon::A2_combinew);
1967 TmpInst.addOperand(Rdd);
1968 TmpInst.addOperand(Rss);
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00001969 TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001970 Inst = TmpInst;
1971 } else {
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001972 Imm.setExpr(HexagonMCExpr::create(
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001973 MCBinaryExpr::createSub(Imm.getExpr(),
1974 MCConstantExpr::create(1, Context), Context),
1975 Context));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001976 Inst.setOpcode(Hexagon::S5_vasrhrnd);
1977 }
1978 break;
1979 }
1980
1981 case Hexagon::A2_not: {
1982 MCInst TmpInst;
1983 MCOperand &Rd = Inst.getOperand(0);
1984 MCOperand &Rs = Inst.getOperand(1);
1985 TmpInst.setOpcode(Hexagon::A2_subri);
1986 TmpInst.addOperand(Rd);
Colin LeMahieu98c8e072016-02-15 18:42:07 +00001987 TmpInst.addOperand(MCOperand::createExpr(
Colin LeMahieuc7b21242016-02-15 18:47:55 +00001988 HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001989 TmpInst.addOperand(Rs);
1990 Inst = TmpInst;
1991 break;
1992 }
Krzysztof Parzyszek5b4a6b62017-02-06 23:18:57 +00001993 case Hexagon::PS_loadrubabs:
1994 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1995 Inst.setOpcode(Hexagon::L2_loadrubgp);
1996 break;
1997 case Hexagon::PS_loadrbabs:
1998 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
1999 Inst.setOpcode(Hexagon::L2_loadrbgp);
2000 break;
2001 case Hexagon::PS_loadruhabs:
2002 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2003 Inst.setOpcode(Hexagon::L2_loadruhgp);
2004 break;
2005 case Hexagon::PS_loadrhabs:
2006 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2007 Inst.setOpcode(Hexagon::L2_loadrhgp);
2008 break;
2009 case Hexagon::PS_loadriabs:
2010 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2011 Inst.setOpcode(Hexagon::L2_loadrigp);
2012 break;
2013 case Hexagon::PS_loadrdabs:
2014 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
2015 Inst.setOpcode(Hexagon::L2_loadrdgp);
2016 break;
2017 case Hexagon::PS_storerbabs:
2018 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2019 Inst.setOpcode(Hexagon::S2_storerbgp);
2020 break;
2021 case Hexagon::PS_storerhabs:
2022 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2023 Inst.setOpcode(Hexagon::S2_storerhgp);
2024 break;
2025 case Hexagon::PS_storerfabs:
2026 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2027 Inst.setOpcode(Hexagon::S2_storerfgp);
2028 break;
2029 case Hexagon::PS_storeriabs:
2030 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2031 Inst.setOpcode(Hexagon::S2_storerigp);
2032 break;
2033 case Hexagon::PS_storerdabs:
2034 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2035 Inst.setOpcode(Hexagon::S2_storerdgp);
2036 break;
2037 case Hexagon::PS_storerbnewabs:
2038 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2039 Inst.setOpcode(Hexagon::S2_storerbnewgp);
2040 break;
2041 case Hexagon::PS_storerhnewabs:
2042 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2043 Inst.setOpcode(Hexagon::S2_storerhnewgp);
2044 break;
2045 case Hexagon::PS_storerinewabs:
2046 if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
2047 Inst.setOpcode(Hexagon::S2_storerinewgp);
2048 break;
Krzysztof Parzyszekc8d676e2017-02-07 17:42:11 +00002049 case Hexagon::A2_zxtb: {
2050 Inst.setOpcode(Hexagon::A2_andir);
2051 Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(255, Context)));
2052 break;
2053 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +00002054 } // switch
2055
2056 return Match_Success;
2057}
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002058
Krzysztof Parzyszekadf02ae2016-04-21 19:49:53 +00002059unsigned HexagonAsmParser::matchRegister(StringRef Name) {
2060 if (unsigned Reg = MatchRegisterName(Name))
2061 return Reg;
2062 return MatchRegisterAltName(Name);
2063}